Vec <T>如何实现iter()?

jim*_*pez 9 rust

我正在查看代码,Vec<T>看看它iter()是如何实现的,因为我想为我的struct实现迭代器:

pub struct Column<T> {
    name: String,
    vec: Vec<T>,
    ...
}
Run Code Online (Sandbox Code Playgroud)

我的目标不是暴露字段并提供迭代器来为列执行循环,最大值,最小值,求和,平均等.

fn test() {
    let col: Column<f32> = ...;
    let max = col.iter().max();
}
Run Code Online (Sandbox Code Playgroud)

我想我会看到Vec<T>迭代是怎么回事.我可以看到iter()在定义SliceExt,但它的实现[T],而不是Vec<T>让我很为难,你怎么能叫iter()Vec<T>

Vla*_*eev 11

实际上,正如fjh所说,这是由于Rust中取消引用运算符函数以及如何解决方法而发生的.

Rust具有特殊的Deref特性,它允许实现它的类型的值被"解引用"以获得另一种类型,通常是自然连接到源类型的类型.例如,像这样的实现:

impl<T> Deref for Vec<T> {
    type Target = [T];

    fn deref<'a>(&'a self) -> &'a [T] { self.as_slice() }
}
Run Code Online (Sandbox Code Playgroud)

意味着将*一元运算符应用于将需要再次借入的Vec<T>产量[T]:

let v: Vec<u32> = vec![0; 10];
let s: &[u32] = &*v;
Run Code Online (Sandbox Code Playgroud)

(注意,即使deref()回报参考,引用操作*的回报Target,而不是&Target-编译器插入自动解引用,如果你不立即借提领值).

这是第一块拼图.第二个是如何解决方法.基本上,当你写一些像

v.iter()
Run Code Online (Sandbox Code Playgroud)

编译器首先尝试查找iter()在类型上定义的v(在本例中Vec<u32>).如果找不到这样的方法,编译器会尝试插入适当数量的*s和&s,以便方法调用生效.在这种情况下,它发现以下内容确实是一个有效的调用:

(&*v).iter()
Run Code Online (Sandbox Code Playgroud)

请记住,DerefVec<T>返回时&[T],切片上iter()确定了方法.这也是您可以调用例如采用&self常规值的方法的方法- 编译器会自动为您插入引用操作.