Rust中IntoIterator::into_iter与values.into_iter()的差异疑问
Rust中
into_iter()点语法与全限定调用的差异问题 在学习Rust的for循环与IntoIterator机制时,我理解了for循环的语法糖展开逻辑,用&mut类型变量测试时发现了如下差异:
代码示例与现象
情况1:全限定调用IntoIterator::into_iter(values)
let values = &mut vec![1., 2., 3., 4., 5.]; { let result = match IntoIterator::into_iter(values) { // values在此处被移动 mut iter => loop { let next; match iter.next() { Some(val) => next = val, None => break, }; let x = next; let () = { println!("{x}"); }; }, }; result } println!("{values:?}"); // 报错:借用已移动的值
情况2:点语法调用values.into_iter()
let values = &mut vec![1., 2., 3., 4., 5.]; { let result = match values.into_iter() { // values未被移动 mut iter => loop { let next; match iter.next() { Some(val) => next = val, None => break, }; let x = next; let () = { println!("{x}"); }; }, }; result } println!("{values:?}"); // 编译器允许此操作,无报错
疑问
values.into_iter()与IntoIterator::into_iter(values)难道不是等价的吗?- 有说法称点语法调用会触发重借用,全限定名调用则不会,这是否正确?该规则在Rust文档何处有说明?
解答
1. 两者并不等价
调用IntoIterator::into_iter(values)时,编译器直接为&mut Vec<f64>匹配IntoIterator实现:当前匹配的是impl IntoIterator for &mut Vec<T>,该实现的into_iter方法接收self(即&mut Vec<T>本身)。由于&mut T不是Copy类型,传递给into_iter(self)会移动原引用变量values,导致后续无法再使用它。
而使用点语法values.into_iter()时,Rust的自动解引用与重借用机制会生效:编译器在方法查找过程中,会自动将原可变引用values重借用为一个临时的&mut Vec<f64>(相当于执行&mut *values),实际调用的是IntoIterator::into_iter(&mut *values)。这个过程并没有移动原变量values,只是创建了一个新的可变借用,因此后续仍能正常使用values。
2. 重借用规则的正确性与文档位置
这个说法是正确的。点语法调用方法时,Rust会执行特定的方法查找流程,其中包含自动解引用和重借用逻辑:
- 调用
x.method()时,编译器会递归尝试为x、*x、**x等(依据Deref/DerefMut实现)查找匹配的方法。 - 对于可变引用场景,当方法需要接收
&mut self时,编译器会自动触发重借用,将&mut x转换为&mut *x,避免移动原引用。
该规则可在以下官方文档中找到说明:
- Rust官方参考手册(Rust Reference)的「方法调用表达式」章节,详细描述了方法查找的完整流程,包括自动解引用和重借用的触发条件。
- 《Rust程序设计语言》一书的「引用与借用」章节涉及了重借用的基础概念,更细节的规则定义在官方参考手册中。
内容的提问来源于stack exchange,提问作者Cesc
相关产品推荐
相关产品推荐

