我正在读一本关于Rust 的书,开始玩Rust macros.所有元变量类型都在这里进行了解释,并提供了示例,最后一个除外——tt.根据这本书,这是一棵"单一的象征树".我很好奇,它是什么?它是用来做什么的?你能举个例子吗?

推荐答案

这个概念的引入是为了确保宏调用中的内容正确匹配()[]{}对.tt将匹配任何单个标记or或任何一对括号/方括号/大括号with their content.

例如,对于以下程序:

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

象征树将是:

  • fn
  • main
  • ()
  • { println!("Hello world!"); }
    • println
    • !
    • ("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!不需要知道实际的格式,也不需要进行复杂的匹配.

Rust相关问答推荐

Rust kill std::processs::child

访问Rust中的隐藏变量

MPSC频道在接收器处阻塞

Gtk4-rs:将监视器作为gdk::monitor获取,而不是作为glib::对象获取

在生存期内将非静态可变引用转换为范围内的静态可变引用

用于判断整数块是否连续的SIMD算法.

将serde_json读入`VEC<;T&>;`( rust 色)时出现问题

在Rust中,Box:ed struct 与普通 struct 在删除顺序上有区别吗?

如果变量本身不是None,如何返回;如果没有,则返回None&Quot;?

为什么我需要 to_string 函数的参考?

如何强制匹配的返回类型为()?

带引脚和不带引脚的比较功能

如何从 x86_64 Mac 构建 M1 Mac?

当你删除一个存在于堆栈中的值时,为什么 rust 不会抱怨

以 `static` 为前缀的闭包是什么意思?我什么时候使用它?

如何将参数传递给Rust 的线程?

SDL2 没有在终端键上触发?

返回引用字符串的future

有没有办法阻止 rust-analyzer 使非活动代码变暗?

如何在宏中的多个参数上编写嵌套循环?