rust 宏扩展忽略标记 `,` 和任何后续内容

2023-12-01

这确实有效

macro_rules! x2 {
    ($x:expr) => {
        [$x, $x]
    };
}


let a = x2!(0)

但非常相似

macro_rules! x2 {
    ($x:expr) => {
        $x, $x     //removed brackets
    };
}


let a = [x2!(0)]   //added brackets

不会并取消第一个分隔符处的扩展,有错误:

macro expansion ignores token `,` and any following
the usage of `x2!` is likely invalid in expression context
  • 为什么分隔符在一个版本中有效而在另一个版本中无效,它们会解包为相同的代码?

  • 有没有一种方法可以构建类似的东西(仅填充数组的一部分,例如let a = [x2!(1),0])?

    • 声明性宏就足够了吗?
    • 如果不是,这会是程序用例的一个用例吗?

我知道工作示例会产生立即有效的表达式,而后者仅在其扩展的上下文中产生,但为什么这很重要? (编译器已经暗示上下文可能会产生无效语法,但事实显然并非如此?)


我知道工作示例会产生立即有效的表达式,而后者仅在其扩展的上下文中产生,但为什么这很重要?

引用我最喜欢的 Rust 宏资源,Rust 宏小书:

Rust 中的所有语法扩展must产生完整的、受支持的语法元素(例如表达式、项目、etc.)。这意味着不可能将语法扩展扩展为部分构造。

在发现this本书的部分。

我认为 Rust 对宏施加了这种卫生约束,因为由严重扩展的宏引起的编译错误很难调试,通常会出现无用的错误消息。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

rust 宏扩展忽略标记 `,` 和任何后续内容 的相关文章

随机推荐