为何对引用调用into_iter不会转移所有权?
为什么对
&mut Vec<String>调用into_iter后仍可继续使用该引用? 先看你给出的对比代码:
fn print_ref(vec: &mut Vec<String>) { vec.into_iter().for_each(|v| println!("{}", v)); vec.into_iter().for_each(|v| println!("{}", v)); // 编译通过 } fn print(vec: Vec<String>) { vec.into_iter().for_each(|v| println!("{}", v)); vec.into_iter().for_each(|v| println!("{}", v)); // 错误:使用已转移的值 }
核心原因在于**&mut Vec<T>的IntoIterator实现并没有转移原始可变引用的所有权,而是通过自动重借用生成了临时的可变引用**,具体分析如下:
1. 区分「引用的所有权」和「原始值的所有权」
- 对于
Vec<T>本身,它的IntoIterator实现接收的是self(即Vec实例的所有权):调用into_iter会直接转移整个Vec的所有权,后续自然无法再使用原变量。 - 对于
&mut Vec<T>(可变引用),它的IntoIterator实现接收的是self——这里的self是可变引用本身,而非原始Vec的所有权。
2. 自动重借用的作用
Rust在方法调用时会自动处理可变引用的重借用:当你对vec: &mut Vec<String>调用into_iter时,Rust会隐式地将vec重借用为一个生命周期更短的临时&mut Vec<String>,然后把这个临时引用的所有权传递给into_iter方法。
当into_iter和后续的for_each执行完毕后,这个临时引用的生命周期就结束了,原始的vec可变引用会自动恢复可用状态,因此可以再次调用into_iter。
3. 结合IntoIterator实现理解
你给出的&mut Vec<T>的IntoIterator实现:
#[stable(feature = "rust1", since = "1.0.0")] impl<'a, T, A: Allocator> IntoIterator for &'a mut Vec<T, A> { type Item = &'a mut T; type IntoIter = slice::IterMut<'a, T>; fn into_iter(self) -> Self::IntoIter { self.iter_mut() } }
这里的self是&'a mut Vec<T, A>,但由于Rust的自动重借用,我们传递给into_iter的并不是原始的vec可变引用,而是它的一个临时重借用版本。这个临时引用的所有权被转移,但原始引用的所有权并未丢失,只是在临时引用的生命周期内被暂时借用。
总结来说:&mut Vec<T>调用into_iter转移的是临时重借用的可变引用的所有权,而非原始可变引用或Vec本身的所有权,因此后续仍可使用原引用。
内容的提问来源于stack exchange,提问作者St.Antario
相关产品推荐
相关产品推荐

