Into<Iterator> 与在线算法的迭代器

Leo*_*all 1 types iterator rust

我正在编写一个在线算法,用一系列函数实现,这些函数采用迭代器并产生迭代器。

当我像这样编写函数时(内容更复杂但在类型方面没有区别):

fn decode<'a, T>(input: T) -> impl Iterator<Item = i16> + 'a
where
    T: Iterator<Item = &'a u8> + 'a,
{
    input.map(|b| i16::from(*b)).filter(|i| *i != 0)
}
Run Code Online (Sandbox Code Playgroud)

看到操场

但是,这使得调用函数不符合人体工学:

let input: Vec<u8> = vec![1, 2, 3, 0];
let v: Vec<i16> = decode(input.iter()).collect();
Run Code Online (Sandbox Code Playgroud)

我更喜欢使用T: Into<Iterator<...,但我不能。当我这样写签名时:

fn decode<'a, T>(input: T) -> impl Iterator<Item = i16> + 'a
where
    T: Into<Iterator<Item = &'a u8>> + 'a,
Run Code Online (Sandbox Code Playgroud)

操场

我收到一个错误,说在编译时不知道返回类型的大小:

fn decode<'a, T>(input: T) -> impl Iterator<Item = i16> + 'a
where
    T: Iterator<Item = &'a u8> + 'a,
{
    input.map(|b| i16::from(*b)).filter(|i| *i != 0)
}
Run Code Online (Sandbox Code Playgroud)

为什么会这样,有没有更好的方法?

She*_*ter 5

使用IntoIterator来代替:

fn decode<'a>(input: impl IntoIterator<Item = &'a u8> + 'a) -> impl Iterator<Item = i16> + 'a {
    input.into_iter().map(|b| i16::from(*b)).filter(|i| *i != 0)
}
Run Code Online (Sandbox Code Playgroud)

Iterator是一个特质,特质没有大小。这就是为什么你不能(还)写:

fn example(x: Iterator<Item = ()>) {}
Run Code Online (Sandbox Code Playgroud)
fn decode<'a>(input: impl IntoIterator<Item = &'a u8> + 'a) -> impl Iterator<Item = i16> + 'a {
    input.into_iter().map(|b| i16::from(*b)).filter(|i| *i != 0)
}
Run Code Online (Sandbox Code Playgroud)

Into 定义为:

pub trait Into<T> {
    fn into(self) -> T;
}
Run Code Online (Sandbox Code Playgroud)

实现的东西Into<dyn Iterator>必须具有 function fn into(self) -> dyn Iterator,返回一个特征。由于特征没有大小,因此(还)不能返回、存储在变量中或作为参数接受。

也可以看看: