2014-08-29 19 views
14

Tôi muốn áp dụng filter trên một iterator và tôi đã đưa ra với lỗi này và nó hoạt động, nhưng nó là siêu tiết:Làm thế nào để so sánh enum mà không cần mô hình phù hợp với

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

Tôi thà viết một cái gì đó như thế này:

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

này mang lại cho tôi một lỗi biên dịch

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

có một thay thế cho đã mô hình rbose phù hợp? Tôi đã tìm kiếm một macro nhưng không thể tìm thấy một macro phù hợp.

Trả lời

26

Trước tiên, bạn có thể sử dụng PartialEq đặc điểm, ví dụ, bằng cách #[derive]:

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

Sau đó, bạn "lý tưởng" biến thể sẽ làm việc như vậy. Tuy nhiên, điều này yêu cầu nội dung của MyEnum cũng thực hiện PartialEq, điều này không phải lúc nào cũng có thể/muốn.

Thứ hai, bạn có thể thực hiện một macro chính mình, một cái gì đó như thế này (mặc dù macro này không hỗ trợ tất cả các loại mô hình, ví dụ như giải pháp thay thế):

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

Sau đó, bạn sẽ sử dụng nó như thế này:

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

an RFC để thêm macro như vậy vào thư viện chuẩn, nhưng vẫn đang được thảo luận.

+1

Câu trả lời hay như bình thường! 'PartialEq' hoạt động như một nét duyên dáng trong trường hợp của tôi. – Christoph

0

Tôi muốn sử dụng mô hình kết hợp, nhưng tôi muốn di chuyển nó đến một phương pháp trên enum để đóng bộ lọc là ngăn nắp:

#[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); 
    } 
} 

Xem thêm:

Các vấn đề liên quan