在Rust的 for循环中,IntoIterator::into_iter(values) 与values.into_iter() 的区别
在阅读for-loops-and-IntoIterator时,我理解了Rust如何把for循环展开成IntoIterator的遍历;到目前为止,一切都挺好。
我开始玩了一下,决定把 &mut 当作值来使用,结果看到如下
let values = &mut vec![1., 2., 3., 4., 5.];
{
let result = match IntoIterator::into_iter(values) { // values moved here
mut iter => loop {
let next;
match iter.next() {
Some(val) => next = val,
None => break,
};
let x = next;
let () = {
println!("{x}");
};
},
};
result
}
println!("{values:?}"); // BOOM: borrow of moved value
let values = &mut vec![1., 2., 3., 4., 5.];
// let mut values = vec![1., 2., 3., 4., 5.];
{
let result = match values.into_iter() { // Why aren't values moved?
mut iter => loop {
let next;
match iter.next() {
Some(val) => next = val,
None => break,
};
let x = next;
let () = {
println!("{x}");
};
},
};
result
}
println!("{values:?}"); // Surprise (to me): Compiler says this is ok, shouldn't `values.into_iter()` have moved values?
难道 values.into_iter() 不等价于 IntoIterator::into_iter(values) 吗?请参见 playground.
后来我在某处看到,用点调用的方法确实会进行重新借用,但用完全限定名调用时不会发生重新借用,这样对吗?
如果我的理解没错,这在文档的哪里有解释?
解决方案
后来我在某处看到,用点调用的方法确实会进行重新借用,但用完全限定名调用时不会发生重新借用,对吗?
差不多。使用路径语法调用一个方法仍然会发生重新借用,前提是目标类型事先被确认为引用类型。但 IntoIterator::into_iter() 是一个trait方法——对 Self 泛型,因此它不会。用例如 <&mut _ as IntoIterator>::into_iter(values) 调用就可以。
如果我的理解没错,这在文档的哪里有解释?我还没找到
不幸的是,关于重新借用的文档讲解得还不够充分。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。