How to allow optional trailing commas in macros?

后端 未结 2 2006
难免孤独
难免孤独 2020-12-15 03:23

Here\'s a synthetic example of what I want:

macro_rules! define_enum {
    ($Name:ident { $($Variant:ident),* }) => {
        pub enum $Name {
                    


        
相关标签:
2条回答
  • 2020-12-15 03:26

    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.

    Make the comma optional

    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.

    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),* $(,)? }) => { 
    //                                 ^^^^^
    
    0 讨论(0)
  • 2020-12-15 03:48

    Change the line

    ($Name:ident { $($Variant:ident),* }) => {
    

    to

    ($Name:ident { $($Variant:ident),* $(,)? }) => {
    

    to add an optional comma at the end. This works in stable Rust / 2018 edition. This syntax also works for other separators like a semicolon.

    0 讨论(0)
提交回复
热议问题