【问题标题】:Why can't I move out of index of Vec<Rc<dyn T>>?为什么我不能移出 Vec<Rc<dyn T>> 的索引?
【发布时间】:2020-11-07 15:35:27
【问题描述】:

首先,很抱歉我无法将一些重复的问题与我的问题进行比较,因为我是 Rust 的初学者。 Possibly duplicate question

编译器为我的代码输出错误:

error[E0507]: cannot move out of index of `std::vec::Vec<std::rc::Rc<dyn T>>`
  --> src/lib.rs:30:18
   |
30 |     let V_last = data.V[V_lastIdx];
   |                  ^^^^^^^^^^^^^^^^^
   |                  |
   |                  move occurs because value has type `std::rc::Rc<dyn T>`, which does not implement the `Copy` trait
   |                  help: consider borrowing here: `&data.V[V_lastIdx]`

请帮我解决问题。

use std::collections::HashMap;
use std::rc::Rc;

trait T {
    fn main(&self, data: &mut Data) -> ();
}

#[derive(Clone)]
struct S1 {
    val: usize,
    t: Rc<dyn T>,
}

struct S2 {
    val: usize,
}

impl T for S1 {
    fn main(&self, data: &mut Data) -> () {
        data.V.push(Rc::new(S2 { val: 123 }));
    }
}

impl T for S2 {
    fn main(&self, data: &mut Data) -> () {}
}

struct Data {
    // Up to 1 instance which may hold about 30MB at most.
    V: Vec<Rc<dyn T>>,
    name_match: HashMap<String, (usize, usize)>,
}

fn round(data: &mut Data) {
    let V_lastIdx = data.V.len() - 1;
    let V_last = data.V[V_lastIdx];
    return V_last.main(data);
}

在我按照编译器建议后,一个新的错误如下所示。

 help: consider borrowing here: `&data.V[V_lastIdx]`
error[E0502]: cannot borrow `*data` as mutable because it is also borrowed as immutable
  --> src/lib.rs:34:11
let V_last= &data.V[V_lastIdx];   
   |                 ------ immutable borrow occurs here
34 |    return V_last.main(data);
   |           ^^^^^^^----^^^^^^
   |           |      |
   |           |      immutable borrow later used by call
   |           mutable borrow occurs here

Playground

现在我已经选择了答案,我注意到我的原始代码可能更简单,如下链接,解决方案代码是从所选答案中借来的。

Playground

【问题讨论】:

  • 阅读编译错误,按照它已经告诉你的去做,然后edit你的问题,然后将其作为stackoverflow.com/questions/57017747/…的副本关闭
  • @Stargateur,请解释它们是如何重复的。
  • @Stargateur,你难道看不到如果两者真的如此重复,我的问题更有价值,因为我的问题显然比你的链接更短更简单。您的链接包含的信息过多且复杂。
  • 您是否尝试过按照编译器的提示执行操作?
  • fwiw,stargateur 的链接很好地解释了为什么编译器的建议不起作用(解决 fn func(&amp;mut Parent, &amp;Child)-type 模式),尽管我同意问答对于新手来说并不是特别容易理解并应用,因为建议的修复非常具体,并不是唯一的解决方法。

标签: rust


【解决方案1】:

当您执行some_vec[index] 时,它会尝试元素移出vec,但that is not allowed。编译器提供的一种解决方法是借用元素:&amp;some_vec[index]。但是,编译器也应该拒绝该解决方案,因为如果允许以 self 作为对 data 中元素的引用的对 main 的调用将/可能被 .push 调用无效。

另一个解决方法,如您的自我回答所示,要求克隆 vec V,以便它们拥有不同的所有权,因此引用不能失效。

更好的解决方案是克隆元素而不是整个向量。考虑到您的元素是 Rcs 并且因此克隆成本低,这是一个特别合理的解决方案:

fn round(data: &mut Data) {
    let V_lastIdx = data.V.len() - 1;
    let V_last = data.V[V_lastIdx].clone();
                               // ^^^^^^^^
    return V_last.main(data);
}

【讨论】:

    【解决方案2】:

    阅读接受的答案后,我意识到下面的解决方案对于我的目的来说根本不是一个好主意。

    我自己通过编辑round函数解决了如下错误。

    之前:

    fn round(data: &mut Data) {
       let V_lastIdx = data.V.len() - 1;
       let V_last= &data.V[V_lastIdx];   
       V_last.main(data)
    }
    

    之后:

    Playground

    fn round(V: Vec<Rc<T>>, data: &mut Data) {
       let V_lastIdx = V.len() - 1;
       let V_last = &V[V_lastIdx];   
       V_last.main(data)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-26
      • 2020-09-10
      • 1970-01-01
      • 2018-08-08
      • 2023-01-09
      • 1970-01-01
      • 2018-08-27
      • 1970-01-01
      相关资源
      最近更新 更多