我正在查看代码,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)
请记住,Deref在Vec<T>返回时&[T],切片上iter()确定了方法.这也是您可以调用例如采用&self常规值的方法的方法- 编译器会自动为您插入引用操作.
| 归档时间: |
|
| 查看次数: |
814 次 |
| 最近记录: |