Конвертировать Ve c<T> в Ve c<U>, если доступно значение From <T>для U - PullRequest
4 голосов
/ 30 января 2020

Я реализовал From<T> for U и ожидал, что смогу вызвать Vec<U>::extend с Vec<T>. Вместо этого я получаю expected T, got U. Какой самый идиоматический c способ исправить это?

struct U;
struct T;

impl From<T> for U {
    fn from(_other: T) -> Self {
        U
    }
}

fn main() {
    let mut v: Vec<U> = Vec::new();
    let other: Vec<T> = Vec::new();

    v.extend(other.into_iter());
}
error[E0271]: type mismatch resolving `<std::vec::IntoIter<T> as std::iter::IntoIterator>::Item == U`
  --> src/main.rs:14:7
   |
14 |     v.extend(other.into_iter());
   |       ^^^^^^ expected struct `T`, found struct `U`
   |
   = note: expected type `T`
              found type `U`

1 Ответ

5 голосов
/ 30 января 2020

Поскольку Extend::extend занимает итератор:

fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T);

Вы можете использовать адаптер карты:

let mut v: Vec<U> = /**/;
let other: Vec<T> = /**/;

v.extend(other.into_iter().map(<U as From<T>>::from));

Детская площадка . Или вы можете исключить указанную реализацию c From и позволить компилятору "сделать для вас ужасную вещь", как @Stargateur упомянул в комментариях:

v.extend(other.into_iter().map(From::from));
...