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

仅含原始类型的Rust结构体仍会被移动?编译疑问解析

问题解答

你忽略的核心要点是:结构体本身不会自动派生Copy trait,哪怕它的所有字段都实现了Copy。

Rust中,只有当一个类型的所有字段都实现了Copy,并且该类型显式派生(或手动实现)了Copy trait时,它才具备可复制性。你的Rectangle结构体虽然字段都是默认实现Copy的u32,但你只派生了Debug,没有派生Copy,所以调用area(rect1)时会触发移动语义——rect1的所有权被转移到area函数中,函数执行完毕后rect1被销毁,后续println中再访问rect1.width和rect1.height自然会编译报错。

两种修复方式

1. 为结构体派生Copy和Clone trait

Copy trait依赖Clone,所以需要一起派生:

#[derive(Debug, Copy, Clone)]
struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };
    let a = area(rect1); // 此时会复制rect1,而非移动
    println!("{} * {} = {}", rect1.width, rect1.height, a); // 可正常访问rect1
}

fn area(rectangle: Rectangle) -> u32 {
    rectangle.width * rectangle.height
}

2. 使用引用传递避免移动

如果不想让结构体实现Copy,可以修改area函数参数为引用类型,仅借用所有权而非转移:

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };
    let a = area(&rect1); // 传递rect1的引用
    println!("{} * {} = {}", rect1.width, rect1.height, a); // rect1所有权仍在main中,可正常访问
}

fn area(rectangle: &Rectangle) -> u32 {
    rectangle.width * rectangle.height // 引用可直接访问字段
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:07:06