结构方法:不能以可变方式借用,因为它也以不可变的方式借用

时间:2020-09-25 19:07:51

标签: rust borrow-checker

我有以下代码(仅作为示例),无法满足借阅检查器的要求。 一种方法修改struct的一个字段,然后调用另一种方法修改另一个。问题是调用第二个方法时,它需要一个依赖于该结构的参数。对second方法的调用不能与参数&self.a一起使用,也不能与&mut self.a一起使用,因为这将是第二次可变的借用。

最后,我通过只用一种方法来处理所有代码来解决了这个问题,但这真是太丑了(在我真正的问题中)。 如何解决呢? (我知道参数&self.a不是必需的,但这不是我想说明的重点...)


struct ABC {
    a: Vec<i32>,    // no Copy trait
    b: i32,
}

impl ABC {
    fn new() -> ABC { ABC {a: vec![0,1], b: 10} }

    fn first(&mut self) {
        self.a.push(2);         // updates one field
        self.second(&self.a);   // uses a method to update the other field
    }

    fn second(&mut self, x: &Vec<i32>) {
        self.b += x[1];
    }
}

fn main() {
    let mut s = ABC::new();
    s.first();
}

Playground here

1 个答案:

答案 0 :(得分:2)

您已经从self.a借来了;因此只要有借贷,就无法继续使用第二种方法。您可以使用to_vec()将数据复制到第二种方法。

struct ABC {
    a: Vec<i32>,    // no Copy trait
    b: i32,
}

impl ABC {
    fn new() -> ABC { ABC {a: vec![0,1], b: 10} }

    fn first(&mut self) {
        self.a.push(2);         // updates one field
        self.second(self.a.to_vec());
    }

    fn second(&mut self, x: Vec<i32>) {
        self.b += x[1];
    }
}

fn main() {
    let mut s = ABC::new();
    s.first();
}

playground

但是如所示,它将复制数据。

最简单的方法是使用self.b方法更新first。这样,我们就不会从self.a

借过两次债
    fn first(&mut self) {
        self.a.push(2);         // updates one field
        self.b += self.a[1];
    }

如果第二秒钟没有从self借用,它将按以下方式工作:

struct ABC {
    a: Vec<i32>, // no Copy trait
    b: i32,
}

impl ABC {
    fn new() -> ABC {
        ABC {
            a: vec![0, 1],
            b: 10,
        }
    }

    fn first(&mut self) {
        self.a.push(2); // updates one field
        Self::second(&mut self.b, &self.a);
    }
    fn second(y: &mut i32, x: &Vec<i32>) {
        *y += x[1];
    }
}

fn main() {
    let mut s = ABC::new();
    s.first();
}

但这与直接通过self.b方法更新first没什么不同。