我正在读一本关于Rust的书,并开始玩Rust macros。所有元变量类型都在那里解释并有示例,除了最后一个 - tt
。根据这本书,它是一个“单一的标记树”。我很好奇,它是什么,它用于什么?你能举个例子吗?
答案 0 :(得分:22)
这是为了确保宏调用中的任何内容正确匹配()
,[]
和{}
对而引入的概念。
例如,对于以下程序:
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)*
表示“所有其余”,只是转发到{{1} }。这意味着format_args!
不需要知道实际的格式并与之进行复杂的匹配。