【问题标题】:Rust macro does not match passed typesRust 宏与传递的类型不匹配
【发布时间】:2016-02-21 12:44:28
【问题描述】:

直接传递给宏的类型模式匹配您所期望的方式,但如果它们通过另一个宏作为ty 传递,它们将停止匹配:

macro_rules! mrtype {
    ( bool )   => ("b");
    ( i32 )    => ("i");
    ( f64 )    => ("f");
    ( &str )   => ("z");
    ( $_t:ty ) => ("o");
}

macro_rules! around {
    ( $t:ty ) => (mrtype!($t));
}

fn main() {
    println!("{}{}{}", mrtype!(i32), around!(i32), around!(&str));
}

这将打印 ioo 而不是 iiz

传递tts 而不是tys 是可行的,但如果您有&str,则需要2 个tts,这会使一切变得不必要地复杂。

【问题讨论】:

    标签: macros rust


    【解决方案1】:

    这行不通,也无法正常工作。

    总结Captures and Expansion Redux chapter of The Little Book of Rust Macros:问题是除了ttident 捕获之外,macro_rules! 完全无法解构或检查捕获的令牌。一旦您以ty 的形式捕获某些内容,它就不可撤销地成为macro_rules! 的黑匣子。

    换句话说:&str 不是类型,就macro_rules! 而言:它是两个标记,&str。但是,当您捕获并将&str 替换为ty 时,它变成了一个“元标记”:&str 类型。两者不再相同,因此不匹配。

    如果您打算稍后匹配或解构令牌,您必须将它们捕获为 tts 或 idents(如果可能)。在这种特定情况下,您可以将around 的规则改写为($($t:tt)*) => (mrtype!($($t)*));,这会保留原始令牌序列。

    【讨论】:

      猜你喜欢
      • 2022-11-07
      • 2016-03-16
      • 2021-04-30
      • 1970-01-01
      • 2020-06-14
      • 1970-01-01
      • 1970-01-01
      • 2021-11-19
      相关资源
      最近更新 更多