用于重复数组元素的 Rust 宏

And*_*gar 6 arrays macros rust rust-macros

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

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

const arr: [u8; 8] = [pad4!(), 0b01111100, 0b10000010, 0b00000010, 0b01111110];
Run Code Online (Sandbox Code Playgroud)

但我收到以下错误:

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

const arr: [u8; 8] = [pad4!(), 0b01111100, 0b10000010, 0b00000010, 0b01111110];
Run Code Online (Sandbox Code Playgroud)

kfe*_*v91 3

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

您当前的宏:

macro_rules! pad4  {
    () => {
        println!("0b00000000, 0b00000000, 0b00000000, 0b00000000");
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下调用:

const arr: [u8; 8] = [pad4!(), 0b01111100, 0b10000010, 0b00000010, 0b01111110];
Run Code Online (Sandbox Code Playgroud)

扩展到这样:

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

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

您可以使用egcargo expand轻松检查宏扩展的结果。


这是以pad4一种有效的方式编写的:

macro_rules! pad4 {
    [$($e:expr),*] => {
        [0b00000000, 0b00000000, 0b00000000, 0b00000000, $($e,)*]
    }
}

const arr: [u8; 8] = pad4![0b01111100, 0b10000010, 0b00000010, 0b01111110];
Run Code Online (Sandbox Code Playgroud)

操场

如果您对 Rust 声明式宏不熟悉,深入学习它们的首选资源是The Little Book of Rust Macros