rust-quiz:009-opaque-metavariable.rs
题目
macro_rules! m {
(1) => { print!("1") };
($tt:tt) => { print!("2") };
}
macro_rules! e {
($e:expr) => { m!($e) };
}
macro_rules! t {
($tt:tt) => { e!($tt); m!($tt); };
}
fn main() {
t!(1);
}
关键
和一些泛型类型方法调用类似,不同场景下回转换为不同的类型。
在macro_rules里面,也会有这种现象。
相关的类型转换和直接透传的类型如下
类型转换
$:block$:expr$:item$:literal$:meta$:pat$:path$:stmt$:ty
类型透传
$:ident$:lifetime$:tt
题解
m!macro_rules! m { (1) => { print!("1") }; ($tt:tt) => { print!("2") }; }这里的主要问题,就是传入的是什么数据。
如果是数值1,没问题肯定打印的是1,如果是tt呢,那就打印2。e!macro_rules! e { ($e:expr) => { m!($e) }; }这里匹配了
expr,然后传入m!。
但是expr隐藏有类型转换的功能,因此传入之后,并非直接数值1了。
而是token-1。t!macro_rules! t { ($tt:tt) => { e!($tt); m!($tt); }; }这里,有直接的判断打印
m!,还有一个中间类型转换e!。
由于传入的是1,如果是直接调用m!,那就会直接打印1。
如果经过e!的转换,当然必当打印2。
答案
因此,答案是21。
本作品采用《CC 协议》,转载必须注明作者和本文链接
关于 LearnKu
推荐文章: