Rust宏用于重复数组元素

6

我正在尝试编写一个Rust宏,用重复的元素填充数组,在这里是零。 这就是我的代码:

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

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

但是我遇到了以下错误:
expected `u8`, found `()`
1个回答

3

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];

游乐场

如果您是首次接触 Rust 声明式宏,学习深入了解它们最好的资源是《Rust 宏小册子》


谢谢,是的,我对Rust还很陌生。所以没有办法像C宏一样插入代码吗? - Andor Polgar
1
我对C或Rust的宏并不是专家,所以我不能确定。除了我在答案中推荐的书籍,您还可以在这个资源中找到有用的信息:将C宏移植到Rust - pretzelhammer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接