【问题标题】:What does the tt metavariable type mean in Rust macros?Rust 宏中的 tt 元变量类型是什么意思?
【发布时间】:2017-03-11 03:59:00
【问题描述】:

我正在阅读一本关于 Rust 的书,并开始使用 Rust macros。除了最后一个 - tt 之外,所有元变量类型都在此处进行了解释并提供了示例。根据这本书,它是一个“单一的令牌树”。我很好奇,它是什么,它是用来做什么的?可以举个例子吗?

【问题讨论】:

    标签: macros rust metaprogramming rust-macros


    【解决方案1】:

    这是为了确保宏调用中的任何内容正确匹配 ()[]{} 对而引入的概念。 tt 将匹配任何单个标记任何一对括号/括号/大括号与其内容

    例如,对于以下程序:

    fn main() {
        println!("Hello world!");
    }
    

    令牌树将是:

    • fn
    • main
    • ()
    • { println!("Hello world!"); }
      • println
      • !
      • ("Hello world!")
        • "Hello world!"
      • ;

    每一个都形成一棵树,其中简单的标记(fnmain 等)是叶子,而任何被 ()[]{} 包围的东西都有一个子树。请注意,( 不会单独出现在令牌树中:如果不匹配相应的 ),则无法匹配 (

    例如:

    macro_rules! {
        (fn $name:ident $params:tt $body:tt) => { /* … */ }
    }
    

    会将上述函数与$name → main$params → ()$body → { println!("Hello world!"); } 匹配。

    令牌树是要求最低的元变量类型:它匹配任何东西。它通常用于具有“不真正关心”部分的宏,尤其是具有“头”和“尾”部分的宏。例如,println! 宏有一个与($fmt:expr, $($arg:tt)*) 匹配的分支,其中$fmt 是格式字符串,$($arg:tt)* 表示“所有其余部分”并且只是转发到format_args!。也就是说println!不需要知道实际的格式,也不需要做复杂的匹配。

    【讨论】:

    • 为什么println! 不使用expr 代替?参数不都是表达式吗?
    • @Tomas 不,他们也可以用named parameters like foo=expr 替换所有的"{foo}"s。
    猜你喜欢
    • 2016-09-15
    • 2015-11-01
    • 2012-04-21
    • 1970-01-01
    • 2019-06-21
    • 1970-01-01
    • 1970-01-01
    • 2022-10-02
    相关资源
    最近更新 更多