我正在尝试创建一个特性,其中包含一些函数,这些函数返回一些内部数据的迭代器,然后可以通过不同的结构实现。一个最小的例子如下:
trait WrapperTrait {
type WrapperIterator: Iterator<Item=u32>;
fn iter(&self) -> Self::WrapperIterator;
}
struct Wrapper {
data: Vec<u32>
}
impl WrapperTrait for Wrapper {
type WrapperIterator = ...;
fn iter(&self) -> Self::WrapperIterator {
return self.data.iter().map(|&x| x);
}
}
但是,WrapperIterator
的类型相当复杂 - 从错误消息(通过类型不匹配创建)中我发现它是:
std::iter::Map<std::slice::Iter<'_, u32>, [closure@borrow.rs:45:37: 45:43]>
有没有办法让Rust推断出WrapperIterator
的正确类型?
答案 0 :(得分:2)
有没有办法让Rust派生出
WrapperIterator
的正确类型?
没有。事实上,这与Rust的做法正好相反。您注释了函数参数和返回类型,然后编译器可以根据它推断出里面类型的类型。
从方法体中推断出顶级类型会导致发生远离引起它们的位置的可怕错误消息。 Haskell以艰难的方式学习了这一点,现在主张所有顶级函数都有明确的类型签名。鲁斯特选择永远不会走那条路。另见this answer;虽然它谈到了生命周期,但许多相同的观点仍然存在。
您未提出的问题(如何返回此迭代器)已经有很多重复:
感谢不要求另一个完全重复。
答案 1 :(得分:0)
不幸的是,这在稳定的 Rust 中尚无法实现,但有 a plan 引入了此功能。如果您想尝试(目前不稳定)功能,您可以在每晚使用 #![feature(min_type_alias_impl_trait)]
进行 Rust。您必须为您的特征添加一个类型参数:
#![feature(min_type_alias_impl_trait)]
trait WrapperTrait<'a> {
type WrapperIterator: Iterator<Item = u32> + 'a;
fn iter(&'a self) -> Self::WrapperIterator;
}
struct Wrapper {
data: Vec<u32>,
}
impl<'a> WrapperTrait<'a> for Wrapper {
type WrapperIterator = impl Iterator<Item = u32> + 'a;
fn iter(&'a self) -> Self::WrapperIterator {
self.data.iter().map(|&x| x)
}
}
要在不向特征添加生命周期参数的情况下做到这一点,还需要另一个不稳定的 Rust 特性:泛型关联类型。
#![feature(min_type_alias_impl_trait)]
#![feature(generic_associated_types)]
trait WrapperTrait {
type WrapperIterator<'a>: Iterator<Item = u32>;
fn iter<'a>(&'a self) -> Self::WrapperIterator<'a>;
}
struct Wrapper {
data: Vec<u32>,
}
impl WrapperTrait for Wrapper {
type WrapperIterator<'a> = impl Iterator<Item = u32>;
fn iter<'a>(&'a self) -> Self::WrapperIterator<'a>{
self.data.iter().map(|&x| x)
}
}