В идеале вы хотели бы:
fn get_items(&self) -> impl Iterator<Item = &String> {
match self {
Foo::Owned(v) => v.into_iter(),
Foo::Refs(v) => v.iter().copied(),
}
}
Вызов copied
здесь для преобразования Iterator<Item = &&String>
в Iterator<Item = &String>
, который мы хотим.Это не работает, потому что два спичечных плеча имеют разные типы:
error[E0308]: match arms have incompatible types
--> src/main.rs:12:30
|
10 | / match self {
11 | | Foo::Owned(v) => v.into_iter(),
| | ------------- this is found to be of type `std::slice::Iter<'_, std::string::String>`
12 | | Foo::Refs(v) => v.iter().copied(),
| | ^^^^^^^^^^^^^^^^^ expected struct `std::slice::Iter`, found struct `std::iter::Copied`
13 | | }
| |_________- `match` arms have incompatible types
|
= note: expected type `std::slice::Iter<'_, std::string::String>`
found type `std::iter::Copied<std::slice::Iter<'_, &std::string::String>>`
Вы можете исправить эту ошибку благодаря itertools
или either
ящики, которые содержат удобный адаптер под названием Either
(*), который позволяет динамически выбирать между двумя итераторами:
fn get_items(&self) -> impl Iterator<Item = &String> {
match self {
Foo::Owned(v) => Either::Left(v.into_iter()),
Foo::Refs(v) => Either::Right(v.iter().copied()),
}
}
детская площадка