You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 23:01:09