【问题标题】:Rust macro for repeating array elements用于重复数组元素的 Rust 宏
【发布时间】:2021-04-28 13:06:54
【问题描述】:

我正在尝试编写一个 Rust 宏,它用重复元素填充数组,在本例中是零。这是我想出的:

macro_rules! pad4  {
    () => {
        println!("0b00000000, 0b00000000, 0b00000000, 0b00000000");
    }
}

const arr: [u8; 8] = [pad4!(), 0b01111100, 0b10000010, 0b00000010, 0b01111110];

但我收到以下错误:

expected `u8`, found `()`

【问题讨论】:

    标签: arrays rust macros rust-macros


    【解决方案1】:

    Rust 宏不是简单的字符串替换,它们对解析的标记进行模式匹配,并且必须返回在调用宏的上下文中有效的 Rust 语法。

    您当前的宏:

    macro_rules! pad4  {
        () => {
            println!("0b00000000, 0b00000000, 0b00000000, 0b00000000");
        }
    }
    

    在此上下文中调用:

    const arr: [u8; 8] = [pad4!(), 0b01111100, 0b10000010, 0b00000010, 0b01111110];
    

    扩展为:

    const arr: [u8; 8] = [
        {
            println!("0b00000000, 0b00000000, 0b00000000, 0b00000000");
        },
        0b01111100,
        0b10000010,
        0b00000010,
        0b01111110,
    ];
    

    这就是您收到错误的原因,因为数组中的第一个表达式块返回 () 而不是预期的 u8

    您可以使用例如cargo expand 方便查看宏展开结果。


    这里是pad4,但写得很好:

    macro_rules! pad4 {
        [$($e:expr),*] => {
            [0b00000000, 0b00000000, 0b00000000, 0b00000000, $($e,)*]
        }
    }
    
    const arr: [u8; 8] = pad4![0b01111100, 0b10000010, 0b00000010, 0b01111110];
    

    playground

    如果您是 Rust 声明性宏的新手,深入学习它们的首选资源是 The Little Book of Rust Macros

    【讨论】:

    • 谢谢,是的,我对 Rust 很陌生。所以绝对没有办法像 C 宏那样插入代码?
    • 我不是 C 或 Rust 的宏专家,所以我不能肯定。除了我在回答中推荐的书之外,您可能还会发现此资源很有帮助:Porting C Macros to Rust
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-24
    • 2015-03-13
    • 2021-09-10
    • 1970-01-01
    相关资源
    最近更新 更多