これが私が欲しいものの合成例です:
_macro_rules! define_enum {
($Name:ident { $($Variant:ident),* }) => {
pub enum $Name {
None,
$($Variant),*,
}
}
}
define_enum!(Foo { A, B });
_
このコードはコンパイルされますが、コンマを追加すると次のようになります。
_define_enum!(Foo { A, B, });
// ^
_
コンパイルは失敗します。私はそれを修正することができます:
_($Name:ident { $($Variant:ident,)* })
// ^
_
しかし、その後define_enum!(Foo { A, B });
は失敗し、
両方のケースを処理するマクロをどのように作成すればよいですか。
_define_enum!(Foo { A, B });
define_enum!(Foo { A, B, });
_
両方のケースを処理するには...両方のケースを処理します。
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() {}
メインの実装を、末尾のコンマが必要なバージョンに移動しました。次に、カンマが欠落しているケースに一致する2番目の句を追加し、カンマを使用してバージョンに書き換えます。
DK。は代替案を指摘しています 、末尾のコンマ自体をオプションにします:
($Name:ident { $($Variant:ident),* $(,)* }) => {
// ^^^^^
これにより、ある実装から別の実装に委任する必要がなくなります。
Rust 2018、Rust 1.32から始まり、?
マクロリピーターを使用して、これをより明確な方法で記述し、複数の末尾を禁止することができますカンマ:
($Name:ident { $($Variant:ident),* $(,)? }) => {
// ^^^^^
行を変更します
($Name:ident { $($Variant:ident),* }) => {
に
($Name:ident { $($Variant:ident),* $(,)? }) => {
末尾にオプションのコンマを追加します。これは安定したRust/2018エディションで機能します。この構文は、セミコロンなどの他の区切り文字でも機能します。