Rust 宏中的 tt 元变量类型是啥意思?
Posted
技术标签:
【中文标题】Rust 宏中的 tt 元变量类型是啥意思?【英文标题】:What does the tt metavariable type mean in Rust macros?Rust 宏中的 tt 元变量类型是什么意思? 【发布时间】:2017-03-11 03:59:00 【问题描述】:我正在阅读一本关于 Rust 的书,并开始使用 Rust macros。除了最后一个 - tt
之外,所有元变量类型都在此处进行了解释并提供了示例。根据这本书,它是一个“单一的令牌树”。我很好奇,它是什么,它是用来做什么的?可以举个例子吗?
【问题讨论】:
【参考方案1】:这是为了确保宏调用中的任何内容正确匹配 ()
、[]
和 对而引入的概念。
tt
将匹配任何单个标记或任何一对括号/括号/大括号与其内容。
例如,对于以下程序:
fn main()
println!("Hello world!");
令牌树将是:
fn
main
()
∅
println!("Hello world!");
println
!
("Hello world!")
"Hello world!"
;
每一个都形成一棵树,其中简单的标记(fn
、main
等)是叶子,而任何被 ()
、[]
或 包围的东西都有一个子树。请注意,
(
不会单独出现在令牌树中:如果不匹配相应的 )
,则无法匹配 (
。
例如:
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。以上是关于Rust 宏中的 tt 元变量类型是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章