Rust向量索引赋值的不对称性:&v[0]与v[0]差异解析
Rust中Vec的
&v[0]与v[0]的区别解析 核心差异本质
v[0]:直接获取元素的所有权(若类型未实现Copy)或拷贝一份元素(若类型实现Copy)&v[0]:获取元素的不可变借用(引用),不会转移所有权或拷贝元素,元素仍保留在Vec中
示例差异的原因
示例1:读取元素用&data[0]
对于i32这种实现了Copy的类型,直接let first = data[0];也能编译通过——它会拷贝一份元素值到first里。但示例中用&data[0]是更通用的写法:
- 如果换成非
Copy类型(比如String),直接data[0]会把元素从Vec中移动出来,导致Vec的该位置失效,后续无法再正常使用Vec; - 用
&data[0]则是借用元素的引用,既不会拷贝(节省开销,尤其对大类型),也不会破坏Vec的完整性,Vec后续仍可正常访问。
示例2:修改元素不用&data[0]
Rust的索引赋值语法data[0] = 15;是编译器提供的语法糖,背后等价于:
*data.index_mut(0) = 15;
index_mut方法会返回元素的可变引用,然后通过解引用*来修改元素本身。你不需要手动加&mut,语法本身已经处理了可变借用的逻辑。如果写成&data[0] = 15,本质是试图给一个不可变引用赋值,这既不符合逻辑也会触发编译错误。
非Copy类型的行为
如果元素类型未实现Copy trait(比如String、自定义结构体):
- 直接
let x = v[0];会触发移动语义:元素会从Vec中被移走,Vec的对应位置变为无效,后续再访问v[0]会编译报错; - 用
let x = &v[0];则是不可变借用,元素仍留在Vec中,Vec保持完整,你可以通过引用读取元素,但不能修改(除非用&mut v[0]获取可变引用)。
举个非Copy类型的例子:
// 错误示例:移动元素导致Vec失效 let mut data = vec![String::from("hello"), String::from("world")]; let first = data[0]; // 第一个String被移动到first中 // println!("{}", data[0]); // 编译错误:move后无法再借用data // 正确示例:借用元素引用 let mut data = vec![String::from("hello"), String::from("world")]; let first = &data[0]; // 不可变借用 println!("{}", first); // 正常输出"hello" println!("{}", data[0]); // 正常输出"hello"
内容的提问来源于stack exchange,提问作者User 10482
相关产品推荐
相关产品推荐

