包龙星

豹头大人!我刚刚把这把尚方宝剑借给常威看了一眼,结果他拿着剑就跑了!现在我也用不了了!

雷豹

蠢货! 尚方宝剑是独一无二的!你把它给了常威(Move),所有权就归他了!你现在就是个光杆司令!

方唐镜

嘿嘿嘿,剑在我手里,我想怎么切就怎么切!包大人,你叫破喉咙也没用,编译器不会理你的!

第十四回:尚方宝剑的所有权

Rust 的核心心法 —— 所有权 (Ownership)。这是 Rust 能够不带保镖(GC)也不练七伤拳(手动释放)的秘密武器。

🗡️ 尚方宝剑三大法则

  1. Rust 中的每一个值都有一个被称为其 所有者(owner)的变量。(宝剑只有一个主人)
  2. 值在任一时刻有且只有一个所有者。(常威拿了,包龙星就没了)
  3. 当所有者(变量)离开作用域,这个值将被丢弃。(常威死了,剑也就埋了)

1. 移动 (Move) —— 覆水难收

在 C++ 里,赋值可能是复制。但在 Rust 里,对于复杂类型(如 String),赋值就是“托付终身”。

fn main() {
    let s1 = String::from("尚方宝剑");
    let s2 = s1; // 移动发生了!s1 的所有权交给了 s2

    // println!("{}, world!", s1); 
    // 错误!包龙星(s1)已经没有剑了,再喊就是欺君之罪(编译错误)!
    
    println!("剑在:{}", s2); // 只有常威(s2)有剑
}
包龙星

那我要是想把剑给他看看,但不想把剑送给他呢?

雷豹

那就用引用 (Reference)!也就是“借用”!借给他看,看完还得还给你!

2. 克隆 (Clone) —— 打造赝品

如果你非要两个人都有剑,那就得去铁匠铺再打一把一模一样的。

let s1 = String::from("尚方宝剑");
let s2 = s1.clone(); // 深度复制,消耗资源

println!("s1 = {}, s2 = {}", s1, s2); // 两人都有剑,开心了

3. 栈上的数据 —— 也就是个烂咸鱼

对于简单的整数(如 i32),它们大小固定,直接在栈上复制,就像咸鱼一样,给他一条,你自己还有一条(Copy Trait)。

let x = 5;
let y = x; // 只是复制了数字,x 依然有效
println!("x = {}, y = {}", x, y);

动手时刻:夺回尚方宝剑

常威抢走了你的剑(String),请修改代码,使用 clone() 或者 & (引用),确保包龙星还能用剑。

fn main() {
    let bao_sword = String::from("上斩昏君");
    
    // 这一行把剑给了常威,导致后面报错
    let chang_wei = bao_sword; 
    
    // 修复它,让包大人也能说话!
    println!("包大人拿出了:{}", bao_sword);
}
查看锦囊妙计

方法一:造假剑(Clone)

let chang_wei = bao_sword.clone();

方法二:借给他看(Reference)

let chang_wei = &bao_sword;
下一回:Slice(切咸鱼的艺术) →