为何在Rust中遍历不可变的非可复制元素Vec是合法的?
问题解答
先看示例代码:
let strings: Vec<String> = something; for s in strings { // uses `s`, the elements of `strings` are moved into `s` }
这段代码合法的核心原因是:不可变绑定 ≠ 不可移动,你混淆了Rust里两个独立的概念——绑定的可变性,和值的所有权转移(移动)。
- 绑定的可变性:
let strings是不可变绑定,意思是你不能给strings重新赋值,也不能调用strings的可变方法(比如push、pop)修改这个Vec的结构。但这并不限制你把整个Vec的所有权转移出去。 - 所有权转移(移动):当你写
for s in strings时,是把strings这个Vec的所有权完整转移给了迭代器。迭代器会逐个取出Vec里的元素,把每个元素的所有权移动到循环变量s中。这个过程结束后,原绑定strings就失效了,你不能再使用它——这完全符合Rust的所有权规则,和Vec是否可变没有关系。
如果不想移动Vec的元素,你可以选择借用迭代:
- 不可变借用:
for s in &strings,此时s是&String类型,不会移动元素,循环结束后strings还能正常使用。 - 可变借用:
for s in &mut strings,此时s是&mut String类型,可以修改元素,但同样不会转移所有权。
你的误解点在于:把“不能修改Vec的结构”和“不能移动Vec的元素”划了等号。实际上,不可变绑定只限制对值的修改操作,不限制所有权的转移——而转移所有权本身就是在消耗这个值,之后它就不再可用了。
内容的提问来源于stack exchange,提问作者user2138149
相关产品推荐
相关产品推荐

