Rust 结构更新语法而不获取所有权

Akk*_*kki 5 rust

#[derive(Debug)]
struct Car {
    company: String,
    model: String,
    cost: i32
}

fn main() {
    let car1 = Car {
        company: String::from("Ford"),
        model: String::from("123xyz"),
        cost: 50000
    };
    let car2 = Car {
        model: String::from("987pqr"),
        cost: 47000,
        ..car1
    };
    println!("{:#?}", car2);
    println!("{:#?}", car1.company);
}
Run Code Online (Sandbox Code Playgroud)

这里编译器正确地告诉我:

println!("{:#?}", car1.company);
                  ^^^^^^^^^^^^ value borrowed here after move
move occurs because `car1.company` has type `String`, which does not implement the `Copy` trait
Run Code Online (Sandbox Code Playgroud)

我知道 String 实例位于堆上,这就是它无法复制的原因,所有权已移至car2.company. 我可以通过这样的方式解决这个用例:

println!("{:#?}", car1.company);
                  ^^^^^^^^^^^^ value borrowed here after move
move occurs because `car1.company` has type `String`, which does not implement the `Copy` trait
Run Code Online (Sandbox Code Playgroud)

问题1:有更好的方法吗?


现在我的问题是,如果结构有很多字段,克隆将创建结构的 car1 实例的副本,只是为了将其值分配给结构的 car2 实例,该实例本身将存储这些值。如果 x 是存储 的实例所需的内存struct Car,

  • 汽车1:x
  • car1.克隆:x
  • 汽车2:x

技术上只需要 2 倍内存,但需要 3 倍内存。

问题2:car2实例化后会car1.clone()超出范围并因此放弃内存吗?

如果是:这种克隆方法就可以了,因为只需要临时额外的 x 内存。

如果不是:那么有没有一种方法可以实现此目标,而无需额外的 x 内存或获取绑定本身的所有权。

Val*_*tin 2

您本质上是在询问是否..car1.clone()执行部分克隆,并且仅克隆缺少的字段,即companyfor car2。

这是一个可能的优化吗?有可能,但clone()可以做任何事情,所以可能不会像剪切和干燥那样执行“部分clone()”。所以答案是否定的,car1.clone()完全是克隆的。

问题1:有更好的方法吗?

我假设您正在使用更新语法 ( ..),因为您有更多的字段。但是,如果没有,则要避免不必要的克隆model。然后您可以显式克隆并分配car1.company.

不过,我想你已经知道这一点了。但如果你想避免不必要的克隆model. 那么这就是替代解决方案。

let car2 = Car {
    company: car1.company.clone(),
    model: String::from("987pqr"),
    cost: 47000,
};
Run Code Online (Sandbox Code Playgroud)

问题2:car2实例化后会car1.clone()超出范围并因此放弃内存吗?

是的。modelfromcar1.clone()在赋值给之后立即被删除car2。但是,company当然不会被删除,因为它被移至car2.