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.
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(),
}
}
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.