我有一些重复的代码
match *x {
A(ref a) => "special",
B(ref a) => "B foo",
C(ref a) => "C foo",
D(ref a) => "D foo",
// ...
}
我想要像
这样的宏macro_rules! generic_fmt {
($T:ident) => {
$T(ref a) => {"$T foo"},
}
}
这样我就可以简化我的匹配
了match *x {
A(ref a) => "special",
generic_fmt!(B),
generic_fmt!(C),
generic_fmt!(D),
// ...
}
最好的方法是什么?我每晚都在使用rustc 1.19.0。
答案 0 :(得分:2)
如果稍微改变你的输出是可以接受的,那么你可以对所有相同的武器使用全能:
match x {
Foo::A(ref a) => println!("special"),
_ => println!("{:?} Foo", x),
}
但这会打印出类型及其参数。如果你在夜间,而不是害怕实验,你可以使用std::intrinsics::type_name
只显示类型名称。
或者你可以使用一个可以完成所有匹配的宏:
macro_rules! gen_match {
($x:ident, $Special:ident, [$( $Foo:ident ),*]) => {
match $x {
Foo::$Special(ref a) => println!("special"),
$(Foo::$Foo(ref a) => println!("{} foo", stringify!($Foo)),)*
}
}
}
并称之为:
gen_match!(x, A, [B, C, D]);
通用格式的变体周围的括号是为了便于阅读,可以从宏定义中删除它们
答案 1 :(得分:1)
你不能完全这样做。宏无法扩展为<Variant> => <Expression>
分支(enum Foo {
A(u32),
B(u32),
C(u32),
D(u32),
}
macro_rules! gen1 {
($Variant:ident) => {
Foo::$Variant(ref a)
}
}
macro_rules! gen2 {
($Variant:ident) => {
concat!(stringify!($Variant), " foo")
}
}
fn print(x: Foo) {
println!("{}", match x {
Foo::A(ref a) => "special",
gen1!(B) => gen2!(B),
gen1!(C) => gen2!(C),
gen1!(D) => gen2!(D),
});
}
fn main() {
print(Foo::A(42));
print(Foo::B(42));
print(Foo::C(42));
print(Foo::D(42));
}
)。
你最接近的可能是这样的:
brew.sh