如何在宏中允许可选的尾随逗号? [英] How to allow optional trailing commas in macros?
问题描述
这是我想要的综合示例:
Here's a synthetic example of what I want:
macro_rules! define_enum {
($Name:ident { $($Variant:ident),* }) => {
pub enum $Name {
None,
$($Variant),*,
}
}
}
define_enum!(Foo { A, B });
该代码可以编译,但是如果添加逗号:
This code compiles, but if add a comma to it:
define_enum!(Foo { A, B, });
// ^
编译失败.我可以用以下方法解决它:
The compilation fails. I can fix it with:
($Name:ident { $($Variant:ident,)* })
// ^
但随后define_enum!(Foo { A, B });
失败,
我应该如何编写宏来处理这两种情况:
How should I write a macro to handle both cases:
define_enum!(Foo { A, B });
define_enum!(Foo { A, B, });
推荐答案
处理这两种情况
您可以通过...处理这两种情况来处理这两种情况:
Handle both cases
You can handle both cases by... handling both cases:
macro_rules! define_enum {
($Name:ident { $($Variant:ident,)* }) => {
pub enum $Name {
None,
$($Variant),*,
}
};
($Name:ident { $($Variant:ident),* }) => {
define_enum!($Name { $($Variant,)* });
};
}
define_enum!(Foo1 { A, B });
define_enum!(Foo2 { A, B, });
fn main() {}
我们已经将主要实现转移到了期望尾随逗号的版本.然后,我们添加了第二个子句,该子句与缺少逗号的情况匹配,并将其重写为带有逗号的版本.
We've moved the main implementation to the version that expects the trailing comma. We then added a second clause that matches the case with the missing comma and rewrites it to the version with a comma.
DK.指出了另一种选择,使尾部逗号本身是可选的:
DK. points out an alternative, making the trailing comma itself optional:
($Name:ident { $($Variant:ident),* $(,)* }) => {
// ^^^^^
这避免了将一个实现委派给另一个实现的需要.
This avoids the need to delegate from one implementation to the other.
在Rust 2018中,从Rust 1.32开始,您可以使用?
宏转发器以更明显的方式编写此代码,并禁止多个尾随逗号:
In Rust 2018, starting with Rust 1.32, you can use the ?
macro repeater to write this in a more obvious manner and disallow multiple trailing commas:
($Name:ident { $($Variant:ident),* $(,)? }) => {
// ^^^^^
这篇关于如何在宏中允许可选的尾随逗号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!