Pet*_*all 5 syntax rust rust-macros rust-decl-macros
我已经看到了@
宏中使用的符号,但我在Rust Book或任何官方文档或博客文章中都找不到它.例如,在此Stack Overflow答案中,它的使用方式如下:
macro_rules! instructions {
(enum $ename:ident {
$($vname:ident ( $($vty: ty),* )),*
}) => {
enum $ename {
$($vname ( $($vty),* )),*
}
impl $ename {
fn len(&self) -> usize {
match self {
$($ename::$vname(..) => instructions!(@count ($($vty),*))),*
}
}
}
};
(@count ()) => (0);
(@count ($a:ty)) => (1);
(@count ($a:ty, $b:ty)) => (2);
(@count ($a:ty, $b:ty, $c:ty)) => (3);
}
instructions! {
enum Instruction {
None(),
One(u8),
Two(u8, u8),
Three(u8, u8, u8)
}
}
fn main() {
println!("{}", Instruction::None().len());
println!("{}", Instruction::One(1).len());
println!("{}", Instruction::Two(1, 2).len());
println!("{}", Instruction::Three(1, 2, 3).len());
}
Run Code Online (Sandbox Code Playgroud)
根据用法,它似乎用于声明另一个主要的本地宏.
这个符号意味着什么,为什么你会使用它而不仅仅是创建另一个顶级宏?
She*_*ter 10
在宏的模式匹配部分中,符号可以表示作者希望它们的意思.前导符号@
通常用于表示宏的"实现细节" - 外部用户不应使用的宏的一部分.
在这个例子中,我使用它来模式匹配元组参数以获得元组参数的计数.
在宏之外,@
符号用于匹配模式,同时还为整个模式指定名称:
match age {
x @ 0 => println!("0: {}", x),
y @ 1 => println!("1: {}", y),
z => println!("{}", z),
}
Run Code Online (Sandbox Code Playgroud)
稍微延伸一下,这个相同的逻辑可以应用于宏中的使用 - 我们对元组进行模式匹配,但也将名称附加到该特定模式.我想我甚至看到人们使用更平行的东西:(count @ ...
.然而,Rust Macros的小书指出:
使用的原因
@
是,从Rust 1.2开始,@
令牌不用于前缀位置; 因此,它不能与任何东西发生冲突.可以根据需要使用其他符号或唯一前缀,但@
已经开始广泛使用,因此使用它可以帮助读者理解您的代码.
而不只是创建另一个顶级宏
创建另一个宏可能是更好的做法,但仅限于现代Rust.在最近对Rust进行更改之前,您可以直接导入宏,对于尝试有选择地导入宏的最终用户而言,拥有多个宏可能会非常棘手.
也可以看看:
归档时间: |
|
查看次数: |
270 次 |
最近记录: |