< 返回版块

CresLeaf 发表于 2021-05-30 14:07

Tags:类型推导, 类型擦除

use std::iter;
use std::iter::DoubleEndedIterator;

type MonoIterator = Box<dyn DoubleEndedIterator<Item = i32>>;
type BiIterator = Box<dyn DoubleEndedIterator<Item = MonoIterator>>;

fn snail(matrix: &[Vec<i32>]) -> Vec<i32> {
    let mut acc: MonoIterator = Box::new(iter::empty());
    let mut content: BiIterator = Box::new(
        matrix
            .to_vec()
            .into_iter()
            .map(|inner| Box::new(inner.into_iter()))
            .collect::<Vec<_>>()
            .into_iter(),
    );
    for head in content {
        acc = Box::new(acc.chain(head));
        content.for_each(|inner| acc = Box::new(acc.chain(inner.next())));
        content = Box::new(
            content
                .map(|inner| Box::new(inner.rev()))
                .collect()
                .into_iter()
                .rev(),
        );
    }
    acc.collect()
}

无法通过类型检查:

error[E0271]: type mismatch resolving `<std::vec::IntoIter<Box<std::vec::IntoIter<i32>>> as Iterator>::Item == Box<(dyn DoubleEndedIterator<Item = i32> + 'static)>`
  --> src/lib.rs:9:35
   |
9  |       let mut content: BiIterator = Box::new(
   |  ___________________________________^
10 | |         matrix
11 | |             .to_vec()
12 | |             .into_iter()
...  |
15 | |             .into_iter(),
16 | |     );
   | |_____^ expected trait object `dyn DoubleEndedIterator`, found struct `std::vec::IntoIter`
   |
   = note: expected struct `Box<(dyn DoubleEndedIterator<Item = i32> + 'static)>`
                found type `Box<std::vec::IntoIter<i32>>`
   = note: required for the cast to the object type `dyn DoubleEndedIterator<Item = Box<(dyn DoubleEndedIterator<Item = i32> + 'static)>>`

去掉某个 workaround 之后:

use std::iter;
use std::iter::DoubleEndedIterator;

type MonoIterator = Box<dyn DoubleEndedIterator<Item = i32>>;
type BiIterator = Box<dyn DoubleEndedIterator<Item = MonoIterator>>;

fn snail(matrix: &[Vec<i32>]) -> Vec<i32> {
    let mut acc: MonoIterator = Box::new(iter::empty());
    let mut content: BiIterator = Box::new(
        matrix
            .to_vec()
            .into_iter()
            .map(|inner| Box::new(inner.into_iter())),
    );
    for head in content {
        acc = Box::new(acc.chain(head));
        content.for_each(|inner| acc = Box::new(acc.chain(inner.next())));
        content = Box::new(
            content
                .map(|inner| Box::new(inner.rev()))
                .collect()
                .into_iter()
                .rev(),
        );
    }
    acc.collect()
}

也不能通过类型检查:

error[E0271]: type mismatch resolving `<[closure@src/lib.rs:13:18: 13:53] as FnOnce<(Vec<i32>,)>>::Output == Box<(dyn DoubleEndedIterator<Item = i32> + 'static)>`
  --> src/lib.rs:9:35
   |
9  |       let mut content: BiIterator = Box::new(
   |  ___________________________________^
10 | |         matrix
11 | |             .to_vec()
12 | |             .into_iter()
13 | |             .map(|inner| Box::new(inner.into_iter())),
14 | |     );
   | |_____^ expected struct `std::vec::IntoIter`, found trait object `dyn DoubleEndedIterator`
   |
   = note: expected struct `Box<std::vec::IntoIter<i32>>`
              found struct `Box<(dyn DoubleEndedIterator<Item = i32> + 'static)>`
   = note: required because of the requirements on the impl of `Iterator` for `Map<std::vec::IntoIter<Vec<i32>>, [closure@src/lib.rs:13:18: 13:53]>`
   = note: required for the cast to the object type `dyn DoubleEndedIterator<Item = Box<(dyn DoubleEndedIterator<Item = i32> + 'static)>>`

是哪里出了问题?


Ext Link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c71104a631a8fc4eeb7a95ed68cdcd91

评论区

写评论
uno 2021-05-30 16:20

上面那段只需要加一个as即可

    let mut content: BiIterator = Box::new(
        matrix
            .to_vec()
            .into_iter()
            .map(|inner| Box::new(inner.into_iter()) as MonoIterator)
            .collect::<Vec<_>>()
            .into_iter(),
    );
1 共 1 条评论, 1 页