rust - 如何从移动到结构中的 Vec 中检索项目?

标签 rust borrow-checker

我有一个包含结构 Vector 的结构,例如

fn main() {
    let x: Vec<Item> = Vec::new(); 
    // assume x is filled with stuff
    do_things_with(x);
}

struct Item {
    value: String,
}

struct Context {
    x: Vec<Item>,
}

impl Context {
    fn get(&mut self, at: usize) -> Item {
        self.x[at]
    }
}

fn do_things_with(x: Vec<Item>) {
    let mut ctx = Context{
        x: x,
    };
    ctx.get(5);
}

我有一个 Vec 的东西,我将它传递给某个函数,该函数创建一个上下文并将传递的值存储在该结构中。然后我想查看这个 Vec 中的项目,所以我有一些辅助函数,例如'get' 将获取指定索引处的项目。

这似乎一切都很好,在 C 或任何其他语言中它会很好,但是 Rust 提示:

'cannot move out of borrowed content'

对于“get”函数,我们尝试访问向量中的项目。

我在这里做错了什么?

最佳答案

这里的问题是 Vec 拥有它包含的 Item 的所有权,但是 Context.get 试图返回 Item 直接(并取得它的所有权)。

如果 Context.get 只是需要让调用者查看向量的内容,它应该返回对 Item 而不是 Item 的引用:

impl Context {
    fn get(&mut self, at: usize) -> &Item {
        &self.x[at]
    }
}

在上面的例子中,Context.get 可以获取对 self 的不可变引用,因为它没有改变任何东西。此外,如果您想允许 Context.get 的调用者修改引用的 Item,您将返回 &mut Item 而不是 &Item:

impl Context {
    fn get(&mut self, at: usize) -> &mut Item {
        &mut self.x[at]
    }
}

编辑:正如@a​​pemanzilla 在评论中有用的注释,如果您希望 Context.get 在 at< 处返回 Item 的单独副本,您还可以让 Item 实现 Clone 特性:

#[derive(Clone)]
struct Item {
    value: String,
}

impl Context {
    fn get(&mut self, at: usize) -> Item {
        self.x[at].clone()
    }

虽然更改返回的项目不会修改包含在 self.x 中的项目;这可能是也可能不是您想要的。

关于rust - 如何从移动到结构中的 Vec 中检索项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55540192/

相关文章:

rust - 对多个方法参数使用相同的引用

从 Rust 调用时,Java JNI 在退出时崩溃

rust - 我如何使用特征方法的默认实现而不是类型的自定义实现?

rust - 为什么我不允许转换包含特征关联类型的值?

rust - 如何通过匹配处理 Rust 中的多个可变借用?

rust - 我怎样才能说服借用检查器允许我缓存值?

rust - 包含一段数据和被引用数据的结构中的生命周期

reflection - 反射的惯用替代

rust - 无法在另一种方法中使用迭代器,因为 "borrow might be used when that temporary is dropped"

rust - 为什么我不能在同一个结构中存储一个值和对该值的引用?