rust - 如何在方法中获取对结构字段的可变引用并调用其他方法而不会引起借用检查器的抱怨?
问题描述
我有这个代码:
struct Player {}
impl Player {
fn update(&mut self) {}
}
struct GameBoard {
p1: Player,
p2: Player,
}
impl GameBoard {
fn update(&mut self) {}
fn update_current_player(&mut self, p1_turn: bool) {
if p1_turn {
self.p1.update()
} else {
self.p2.update();
}
self.update();
if p1_turn {
self.p1.update()
} else {
self.p2.update();
}
}
}
if
每次我想更新当前播放器时,我都不想输入该语句。在我用过的其他语言中,我会写这样的东西:
struct Player {}
impl Player {
fn update(&mut self) {}
}
struct GameBoard {
p1: Player,
p2: Player,
}
impl GameBoard {
fn update(&mut self) {}
fn update_current_player(&mut self, p1_turn: bool) {
let p = if p1_turn { &mut self.p1 } else { &mut self.p2 };
p.update();
self.update();
p.update();
}
}
但这让借用检查器很恼火:
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> src/lib.rs:18:9
|
15 | let p = if p1_turn { &mut self.p1 } else { &mut self.p2 };
| ------------ first mutable borrow occurs here
...
18 | self.update();
| ^^^^ second mutable borrow occurs here
19 |
20 | p.update();
| - first borrow later used here
必须有某种方法不必if
每次都输入语句。我也不希望将if
语句分解成一个函数p1_turn
,因为写出函数调用仍然相当长。有人有建议吗?
我理解如果您在堆内Enum
或堆上访问数据,为什么这种模式是不安全的,因为调用self.update()
可能会使引用无效,但在这种情况下,引用不可能被任何代码无效,self.update()
因为它只是引用到结构的一个字段。
解决方案
必须有某种方法不必
if
每次都输入语句。我也不希望将if
语句分解成一个函数p1_turn
,因为写出函数调用仍然相当长。
鉴于这些要求,您可以创建一个匿名闭包来捕获p1_turn
变量并重新使用它。但是,为了避免重叠的可变借用,您必须将&mut self
其作为参数传递给闭包。例子:
struct Player {}
impl Player {
fn update(&mut self) {}
}
struct GameBoard {
p1: Player,
p2: Player,
}
impl GameBoard {
fn update(&mut self) {}
fn update_current_player(&mut self, p1_turn: bool) {
let p_update = |gb: &mut GameBoard| {
if p1_turn {
gb.p1.update();
} else {
gb.p2.update();
}
};
p_update(self);
self.update();
p_update(self);
}
}
推荐阅读
- javascript - JS链接不起作用
- mysql - 将 SQL Server 存储过程重写为 MySQL(MariaDB)
- amazon-route53 - AWS IOT 端点和 Route53
- ios - 在动画期间获取旋转角度/从 CATransform3D 获取旋转角度
- javascript - 带有 javascript 对象的加号运算符
- c# - 如何在 xamarin 表单中从自定义渲染器导航到内容页面
- laravel - 预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段 X-CSRF-TOKEN
- python - Tkinter:AttributeError:“NoneType”对象没有属性“插入”
- ansible - Ansible json_query - 在语法上苦苦挣扎
- javascript - javascript for 循环在循环内更新和记录数组时表现奇怪