简体   繁体   中英

How to return an iterator for single or multiple values in enum

Consider the following code:

struct MediaKind;
struct OtherFields;

enum Media {
    Single(MediaKind),
    Group(Vec<MediaKind>, OtherFields),
}

impl Media {
    fn iter(&self) -> impl Iterator<Item = &MediaKind> {
        match self {
            Self::Single(media) => [media].iter(),
            Self::Group(media_vec, _) => media_vec.iter(),
        }
    }
}

Compile error:

error[E0308]: `match` arms have incompatible types
  --> src/lib.rs:13:42
   |
11 | /         match self {
12 | |             Self::Single(media) => [media].iter(),
   | |                                    -------------- this is found to be of type `std::slice::Iter<'_, &MediaKind>`
13 | |             Self::Group(media_vec, _) => media_vec.iter(),
   | |                                          ^^^^^^^^^^^^^^^^ expected `&MediaKind`, found struct `MediaKind`
14 | |         }
   | |_________- `match` arms have incompatible types
   |
   = note: expected struct `std::slice::Iter<'_, &MediaKind>`
              found struct `std::slice::Iter<'_, MediaKind>`

Because the Group arm may contain additional fields, replacing this entire enum with a Vec is not a preferred solution.

I have tried either crate to solve the problem in the following way:

fn iter(&self) -> impl Iterator<Item = &MediaKind> {
    use either::*;

    match self {
        Self::Single(media) => Left([media].into_iter()),
        Self::Group(media_vec, _) => Right(media_vec.iter()),
    }
}

But I'm wondering if it's possible to fix it without depending on an external crate.

> Link to playground

In this case, because one case is a slice iterator and the other is one element, you can use a trick: std::slice::from_ref() :

fn iter(&self) -> impl Iterator<Item = &MediaKind> {
    match self {
        Self::Single(media) => std::slice::from_ref(media).iter(),
        Self::Group(media_vec, _) => media_vec.iter(),
    }
}

Playground .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM