结构方法:不能借用为可变的,因为它也被借用为不可变的
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();
}
您已经从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();
}
但如前所述,它会复制数据。
最简单的方法是在 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
没有太大区别
我有以下代码(只是一个例子)不能满足借用检查器的要求。
一种方法修改 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();
}
您已经从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();
}
但如前所述,它会复制数据。
最简单的方法是在 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
没有太大区别