我定义了一个Attribute
类型,我有一个Vec<Attribute>
我正在循环检索&#34; best&#34;一。这与我的第一次尝试类似:
#[derive(Debug)]
struct Attribute;
impl Attribute {
fn new() -> Self {
Self
}
}
fn example(attrs: Vec<Attribute>, root: &mut Attribute) {
let mut best_attr = &Attribute::new();
for a in attrs.iter() {
if is_best(a) {
best_attr = a;
}
}
*root = *best_attr;
}
// simplified for example
fn is_best(_: &Attribute) -> bool {
true
}
我遇到了以下编译错误:
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:17:13
|
17 | *root = *best_attr;
| ^^^^^^^^^^ cannot move out of borrowed content
在搜索了一些解决方案后,我通过执行以下操作解决了错误:
#[derive(Clone)]
结构Attribute
属性
*root = best_attr.clone();
我不完全理解为什么会这样,我觉得这对我遇到的问题是一个粗略的解决方案。这是如何解决这个错误的,这是解决这个问题的正确方法吗?
答案 0 :(得分:2)
您正在体验Rust内存模型的基础:
Copy
的类型)以此代码为例:
let x = String::new();
let y = x;
println!("{}", x);
它会生成错误:
error[E0382]: borrow of moved value: `x`
--> src/main.rs:4:20
|
3 | let y = x;
| - value moved here
4 | println!("{}", x);
| ^ value borrowed here after move
|
= note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait
类型x
的 String
不可隐式复制,因此已移动到y
。 x
不能再使用了。
在您的代码中,当您撰写*root = *best_attr
时,您首先取消引用引用best_attr
,然后将解除引用的值分配给*root
。您的Attribute
类型不是Copy
,因此此分配应为移动。
然后,编译器抱怨:
cannot move out of borrowed content
实际上,best_attr
是一个不可变引用,不允许你拥有它背后的值(它甚至不允许修改它)。允许这样的移动会使对象拥有引用后面的值处于未定义状态,这正是Rust旨在防止的。
在这种情况下,您最好的选择是创建一个与第一个具有相同值的新对象,这正是特征Clone
的作用。
#[derive(Clone)]
允许您将结构标记为Clone
- 只要其所有字段均为Clone
。在更复杂的情况下,您必须手动实施这一特性。