Почему значение не преобразуется в типаж-объект с динамической отправкой в ​​закрытии?

Учитывая следующий код:

use std::iter::Iterator;

trait Sequence {
    type SeqType: Iterator<Item = u32>;

    fn seq(&self) -> Option<Self::SeqType>;
}

struct Doubler<'a>(Option<&'a [u32]>);

impl<'a> Sequence for Doubler<'a> {
    type SeqType = Box<dyn Iterator<Item = u32>>;

    // NOT WORKING
    fn seq(&self) -> Option<Self::SeqType> {
        self.0
            .map(|v| Box::new(v.to_vec().into_iter().map(|x| x * 2)))
    }
}

fn print_seq<S: Sequence>(seq: S) {
    let v: Option<Vec<u32>> = seq.seq().map(|i| i.collect());
    println!("{:?}", v);
}

fn main() {
    let v = vec![1, 2, 3, 4];
    print_seq(Doubler(Some(&v)));
}

Компилятор будет жаловаться:

error[E0308]: mismatched types
  --> src/main.rs:16:9
   |
15 |       fn seq(&self) -> Option<Self::SeqType> {
   |                        --------------------- expected `std::option::Option<std::boxed::Box<(dyn std::iter::Iterator<Item = u32> + 'static)>>` because of return type
16 | /         self.0
17 | |             .map(|v| Box::new(v.to_vec().into_iter().map(|x| x * 2)))
   | |_____________________________________________________________________^ expected trait object `dyn std::iter::Iterator`, found struct `std::iter::Map`
   |
   = note: expected enum `std::option::Option<std::boxed::Box<(dyn std::iter::Iterator<Item = u32> + 'static)>>`
              found enum `std::option::Option<std::boxed::Box<std::iter::Map<std::vec::IntoIter<u32>, [closure@src/main.rs:17:58: 17:67]>>>`

Но работает заменой seq:

fn seq(&self) -> Option<Self::SeqType> {
    fn convert(s: &[u32]) -> Box<dyn Iterator<Item = u32>> {
        Box::new(s.to_vec().into_iter().map(|x| x * 2))
    }
    self.0.map(convert)
}

Код можно протестировать здесь.

Единственное отличие состоит в том, что в неудачном примере используется замыкание, а в другом - функция (с именем?), Но логика та же. Это похоже на пожизненную проблему, но я так и не смог ее решить. Кроме того, предполагается, что Option::map нетерпеливо потребляет значение, тогда следует немедленно использовать закрытие.

Почему пример закрытия терпит неудачу?


person Rodolfo    schedule 20.10.2020    source источник
comment
Похоже, на ваш вопрос можно ответить ответами Используйте Option :: map to Box :: new объект черты не работает и Как работает механизм создания черт в рамке?. В противном случае отредактируйте свой вопрос, чтобы объяснить различия. В противном случае мы можем отметить этот вопрос как уже полученный.   -  person Shepmaster    schedule 20.10.2020
comment
Вы можете исправить пример map, добавив as _, чтобы указать компилятору, где добавить принуждение.   -  person trentcl    schedule 20.10.2020
comment
Итак, есть неявное принуждение, о котором я никогда не знал. Спасибо Shepmaster и trentcl   -  person Rodolfo    schedule 20.10.2020