Compiler errors &引用;无法移出借用的内容“;适用于Vec,但不适用于u64

Compiler errors &引用;无法移出借用的内容“;适用于Vec,但不适用于u64,compiler-errors,rust,borrow-checker,Compiler Errors,Rust,Borrow Checker,以下代码引发错误: struct Foo { a: Vec<u64>, } impl Foo { fn change_a(&mut self, new_a: Vec<u64>) { self.a = *choose(&self.a, &new_a); } } fn choose<'a>(x: &'a Vec<u64>, y: &'a Vec<u64>)

以下代码引发错误:

struct Foo {
    a: Vec<u64>,
}

impl Foo {
    fn change_a(&mut self, new_a: Vec<u64>) {
        self.a = *choose(&self.a, &new_a);
    }
}

fn choose<'a>(x: &'a Vec<u64>, y: &'a Vec<u64>) -> &'a Vec<u64> {
    return if x > y { x } else { y };
}

fn main() {
    let mut foo = Foo { a: vec![1] };
    foo.change_a(vec![3]);
    println!("{:?}", foo.a);
}
如果我将
Vec
s替换为
u64
s


区别是什么?

区别在于
u64
实现而
Vec
不实现。当您尝试移动实现
Copy
的类型的值,但无法移动要从中移动的值时,编译器实际上不会移动它,而是会复制它,这就是为什么带有
u64
的版本可以很好地编译。

不同之处在于
u64
实现而
Vec
不实现。当您尝试移动实现了
Copy
的类型的值,但无法移动要从中移动的值时,编译器实际上不会移动它,而是会复制它,这就是为什么带有
u64
的版本可以很好地编译。

原语类型
u64
实现。这意味着
u64
具有“复制语义”:如果编译器发现我们正试图获得
T:copy
的所有权,但仍使用从中移动的值,则将复制
T

Vec
不是
Copy
,而是
Clone
,这意味着我们可以这样做

self.a = choose(& self.a, & new_a).clone();
来解决这个问题


是复制语义的另一个示例,使用您的示例原语类型
u64
实现。这意味着
u64
具有“复制语义”:如果编译器发现我们正试图获得
T:copy
的所有权,但仍使用从中移动的值,则将复制
T

Vec
不是
Copy
,而是
Clone
,这意味着我们可以这样做

self.a = choose(& self.a, & new_a).clone();
来解决这个问题


使用您的示例的复制语义的另一个示例是否与向量元素的生命周期与向量本身分离有关?i、 e.每个向量元素的生存期至少与
self.a
一样长。可能与向量元素的生存期与向量本身分离有关?i、 e.每个向量元素的寿命至少与self.a
一样长。