2017-03-31 13 views
7

यहाँ मैं क्या चाहते हैं के एक सिंथेटिक उदाहरण है:मैक्रोज़ में वैकल्पिक पिछला कॉमा कैसे अनुमति दें?

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, }); 

उत्तर

11

आप से दोनों ही मामलों संभाल कर सकते हैं ... से निपटने दोनों मामले:

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() {} 

हमने मुख्य कार्यान्वयन को उस संस्करण में स्थानांतरित कर दिया है जो एक्सप पिछली कॉमा को निकालता है। इसके बाद हमने एक दूसरा खंड जोड़ा जो लापता अल्पविराम के साथ मामले से मेल खाता है और इसे अल्पविराम के साथ संस्करण में फिर से लिखता है।


DK. points out an alternative, अनुगामी अल्पविराम ही वैकल्पिक बनाने:

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

यह एक कार्यान्वयन से दूसरे को सौंपने के लिए जरूरत से बचा जाता है।

जंग की रात संस्करणों में, आप macro_at_most_once_rep सुविधा का उपयोग एक और अधिक स्पष्ट तरीके से इस लिखने के लिए कर सकते हैं और कई अनुगामी अल्पविराम के नामंज़ूर: जब आप `$ का उपयोग कर सकते

($Name:ident { $($Variant:ident),* $(,)? }) => { 
//         ^
+1

क्यों कि से परेशान (,) * मैक्रो पैटर्न में बंद ब्रेस से ठीक पहले? एक नियम, और पीछे की ओर अल्पविराम के लिए काम करता है ... एस। ठीक है, तो यह spec के बाहर * थोड़ा * है, लेकिन पुनरावृत्ति पर कटौती। –

+1

@ डीके। मुख्य कारण यह है कि मुझे एहसास नहीं हुआ कि आप ऐसा कर सकते हैं ;-) मुझे पूरी तरह से क्रांतिकारी उत्तर की तरह लगता है; कृपया इसे जोड़ें! – Shepmaster

+0

एह, आप पहले यहां थे, और आप पहले से ही चार अर्थहीन इंटरनेट अंक प्राप्त कर चुके हैं। दोनों में से सर्वश्रेष्ठ के लिए एक विकल्प के रूप में इसे संपादित करने के लिए तेज़ी से। –

संबंधित मुद्दे