如何从一个for循环用户定义的类型?

问题描述 投票:1回答:1

我定义的Attribute类型和我有我遍历检索“最好”的一个Vec<Attribute>。这是类似于我第一次尝试:

#[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

一些寻找解决的办法,我通过以下操作解决了错误:

  1. 添加#[derive(Clone)]属性我Attribute结构
  2. 更换用*root = best_attr.clone();最后陈述

我不完全理解为什么这个作品,我觉得这样是一个粗略的解决方案,我是有这个问题。这是如何解决的错误,这是解决这个问题的正确方法是什么?

reference rust borrow-checker
1个回答
2
投票

您所遇到的锈内存模型的基础:

  • 每个对象可以(而且必须!)仅正好一个其他对象所拥有
  • 大多数类型从不隐复制并始终移动(有一些例外:实现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的,是不能够复制隐式,因此已移入yx不能再使用。

在你的代码,当你写*root = *best_attr,你第一次提领参考best_attr,然后分配提领值*root。你Attribute类型不Copy,因此这项任务应该是一招。

然后,编译器会抱怨:

cannot move out of borrowed content

事实上,best_attr是一个不变的参考,它不允许你把它背后的价值的所有权(它甚至不允许修改它)。允许这样的举动将使拥有处于不确定状态,这正是防锈目的是防止后面的参考资料值的对象。


在这种情况下,最好的选择确实是创建一个新的对象具有相同的值作为第一位的,这也正是性状Clone用于制造。

#[derive(Clone)]允许您标记您的结构为Clone-能,只要所有的字段都是Clone。在更复杂的情况下,你必须实现由手工特质。

© www.soinside.com 2019 - 2024. All rights reserved.