Rust中两种赋值语句差异探究:`let y=x` vs `let &mut y=&mut x`
Rust两种赋值语句的差异分析
先看你的代码示例:
let mut x = 1; let mut y = x; // (1) let &mut mut y = &mut x; // (2)
这两个语句表面效果看似一致,但底层逻辑完全不同,且语句(2)确实具备语句(1)没有的额外能力,核心差异在于是否涉及引用的模式匹配。
一、语句(1)的基础赋值逻辑
let mut y = x;是最常规的变量赋值:
- 因为
x是i32(默认整数类型,属于Copy类型),这里会直接拷贝x的值到y,赋值后x和y是两个独立变量,修改其中一个不会影响另一个。 - 如果
x是非Copy类型(比如String),这里会触发所有权移动,赋值后x会失效,无法再被使用。
二、语句(2)的模式解构逻辑
let &mut mut y = &mut x;本质是模式匹配,用左侧的模式去解构右侧的可变引用:
- 右侧
&mut x是指向x的可变引用(类型为&mut i32); - 左侧
&mut mut y是匹配模式,它会提取引用指向的值——因为i32是Copy类型,所以最终y拿到x的拷贝;若x是非Copy类型,这种写法会直接编译报错(无法从可变引用后移动非Copy值)。 - 代码里的
mut mut是语法冗余,不影响逻辑,正确写法应为let &mut y = &mut x;。
三、语句(2)的额外功能
语句(2)的模式匹配写法,在复杂引用场景下的优势是语句(1)不具备的:
- 解构嵌套引用:面对多层嵌套的引用(比如
&&mut i32),无需手动多层解引用,直接用对应模式就能提取底层值。例如:
这种场景下,若用语句(1)的写法let mut x = 1; let ref1 = &mut x; let ref2 = &mut ref1; // 用模式解构直接拿到x的底层值 let &&mut y = ref2; println!("{}", y); // 输出1let y = ref2;,y会是一个&mut &mut i32类型的引用,而非i32值,必须手动写let y = **ref2;才能拿到值,模式匹配写法更简洁直观。 - 配合复杂模式使用:在匹配枚举、结构体中的引用变体时,模式解构可以直接提取引用指向的内部值,无需额外解引用操作。
内容的提问来源于stack exchange,提问作者user22608671
相关产品推荐
相关产品推荐

