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

String与&String的move行为差异原因探究

问题解答

先纠正你的一个关键误解

你猜测&String未实现Copy trait是错误的:所有共享引用类型(&T)默认都实现了Copy trait,这才是第一个示例能正常运行的核心原因。

示例1的运行逻辑

fn main() {
    let dd = String::from("jellooooo");
    let ee = ⅆ
    let ff = ee;

    println!("{}", *ee);    
}
  • ee是指向dd的共享引用(类型&String),因为&String实现了Copy,所以执行let ff = ee时,是对ee进行逐位复制,复制的是指向dd的指针值。
  • 复制完成后,ee和ff都是指向同一个String的有效引用,所有权规则允许多个共享引用同时存在,所以后续依然可以正常访问ee。

示例2的运行逻辑

fn main() {     
    let dd01 = String::from("belloooo");
    let ee01 = dd01;
    
    println!("{}", dd01);
}   
  • String类型没有实现Copy trait,所以执行let ee01 = dd01时,会触发所有权转移(move):dd01的所有权完全转移给ee01,原变量dd01立即变成无效状态。
  • Rust禁止访问无效的变量,这是为了避免双重释放问题:String的堆内存由所有者负责释放,如果允许dd01继续被访问,后续可能会出现两个变量同时认为自己拥有这块堆内存,最终导致重复释放内存的错误。

回答你的核心问题

编译器不需要知晓类型是栈分配还是堆分配,它只关注两个点:

  1. 该类型是否实现了Copy trait;
  2. 所有权转移的规则。

Rust的move/Copy机制是基于所有权系统和trait实现的,和类型的内存布局(栈/堆)没有直接关联:

  • 即使是完全在栈上的类型,只要没实现Copy,赋值时也会触发move;
  • 反之,像共享引用这种涉及指针(间接指向堆内存)的类型,因为实现了Copy,赋值时就是简单的复制操作。

内容的提问来源于stack exchange,提问作者whowhenhow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 16:35:35