tt 元变量类型在 Rust 宏中意味着什么?
What does the tt metavariable type mean in Rust macros?
我正在读一本关于 Rust 的书,并开始玩 Rust macros。除了最后一个 - tt
之外,所有元变量类型都在此处进行了解释并提供了示例。按照书中的说法,它是一棵“单令牌树”。我很好奇,它是什么以及它的用途是什么?能举个例子吗?
引入这个概念是为了确保宏调用中的任何内容都能正确匹配 ()
、[]
和 {}
对。 tt
将匹配任何单个标记 或 任何一对 parenthesis/brackets/braces 及其内容 .
例如,对于以下程序:
fn main() {
println!("Hello world!");
}
令牌树将是:
fn
main
()
- ∅
{ println!("Hello world!"); }
println
!
("Hello world!")
"Hello world!"
;
每个都形成一棵树,其中简单标记(fn
、main
等)是叶子,任何被 ()
、[]
或 [=14 包围的东西=] 有一个子树。请注意 (
不会单独出现在令牌树中:如果不匹配相应的 )
.
就不可能匹配 (
例如:
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!
不需要知道实际格式并与之进行复杂的匹配。
我正在读一本关于 Rust 的书,并开始玩 Rust macros。除了最后一个 - tt
之外,所有元变量类型都在此处进行了解释并提供了示例。按照书中的说法,它是一棵“单令牌树”。我很好奇,它是什么以及它的用途是什么?能举个例子吗?
引入这个概念是为了确保宏调用中的任何内容都能正确匹配 ()
、[]
和 {}
对。 tt
将匹配任何单个标记 或 任何一对 parenthesis/brackets/braces 及其内容 .
例如,对于以下程序:
fn main() {
println!("Hello world!");
}
令牌树将是:
fn
main
()
- ∅
{ println!("Hello world!"); }
println
!
("Hello world!")
"Hello world!"
;
每个都形成一棵树,其中简单标记(fn
、main
等)是叶子,任何被 ()
、[]
或 [=14 包围的东西=] 有一个子树。请注意 (
不会单独出现在令牌树中:如果不匹配相应的 )
.
(
例如:
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!
不需要知道实际格式并与之进行复杂的匹配。