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

Struct methods: Cannot borrow as mutable because it is also borrowed as immutable

我有以下代码(只是一个例子)不能满足借用检查器的要求。 一种方法修改 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.

您已经从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

但如前所述,它会复制数据。

最简单的方法是在 first 方法中更新 self.b。这样我们就不会从 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();
}

不过和直接用first方法更新self.b没有太大区别