2014-08-29 5 views
14

मैं पुनरावर्तक पर filter लागू करना चाहते हैं और मैं इस एक के साथ आया था और यह काम करता पैटर्न के बिना enum तुलना करने के लिए, लेकिन यह सुपर वर्बोज़ है:कैसे मिलान

.filter(|ref my_struct| match my_struct.my_enum { Unknown => false, _ => true }) 

मैं नहीं बल्कि कुछ इस तरह लिखना होगा:

.filter(|ref my_struct| my_struct.my_enum != Unknown) 

यह मैं एक संकलन त्रुटि

binary operation `!=` cannot be applied to type `MyEnum` 

देता है वहाँ के लिए एक विकल्प ve है rbose पैटर्न मिलान? मैंने एक मैक्रो की तलाश की लेकिन एक उपयुक्त नहीं मिला।

उत्तर

26

सबसे पहले, आप #[derive] द्वारा उदाहरण के लिए PartialEq विशेषता का उपयोग कर सकते,:

#[derive(PartialEq)] 
enum MyEnum { ... } 

फिर अपने 'आदर्श' संस्करण है के रूप में काम करेंगे। हालांकि, इसके लिए MyEnum की सामग्री भी PartialEq लागू करती है, जो हमेशा संभव/इच्छित नहीं होती है।

दूसरे, आप एक मैक्रो अपने आप को, कुछ इस तरह लागू कर सकते हैं (हालांकि यह मैक्रो पैटर्न के सभी प्रकार का समर्थन नहीं करता, उदाहरण के लिए, विकल्प):

macro_rules! matches(
    ($e:expr, $p:pat) => (
     match $e { 
      $p => true, 
      _ => false 
     } 
    ) 
) 

तो फिर तुम इस तरह यह प्रयोग करेंगे:

.filter(|ref my_struct| !matches!(my_struct.my_enum, Unknown)) 

मानक पुस्तकालय में ऐसा मैक्रो जोड़ने के लिए an RFC है, लेकिन यह अभी भी चर्चा में है।

+1

सामान्य रूप से महान उत्तर! 'PartialEq' मेरे मामले में एक आकर्षक की तरह काम करता है। – Christoph

0

मैं पैटर्न मिलान का उपयोग करना चाहते हैं, लेकिन मैं enum पर एक विधि पर ले जाते हैं चाहते हैं ताकि फिल्टर बंद tidier है:

#[derive(Debug)] 
enum Thing { 
    One(i32), 
    Two(String), 
    Unknown, 
} 

impl Thing { 
    fn is_unknown(&self) -> bool { 
     match *self { 
      Thing::Unknown => true, 
      _ => false, 
     } 
    } 
} 

fn main() { 
    let things = vec![Thing::One(42), Thing::Two("hello".into()), Thing::Unknown]; 
    for t in things.iter().filter(|s| !s.is_unknown()) { 
     println!("{:?}", t); 
    } 
} 

यह भी देखें:

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