gui*_*tes 2 mutability rust borrow-checker
游戏的最小示例,玩家拥有一个位置并随着时间的流逝而走动。编译如下:
use std::thread::sleep;
use std::time::Duration;
struct Player {
position: usize,
}
impl Player {
fn new() -> Self {
Self { position: 0 }
}
}
impl Player {
fn get_position(&self) -> usize {
self.position
}
}
impl Player {
fn walk(&mut self) {
self.position += 1;
}
}
fn main() {
let mut player = Player::new();
loop {
player.walk();
sleep(Duration::from_secs(1));
}
}
Run Code Online (Sandbox Code Playgroud)
如果玩家借用该位置而不是拥有它,则不会编译:
use std::thread::sleep;
use std::time::Duration;
struct Player<'a> {
position: &'a mut usize,
}
impl<'a> Player<'a> {
fn new(position: &'a mut usize) -> Self {
Self { position }
}
}
impl<'a> Player<'a> {
fn get_position(&'a self) -> usize {
*self.position
}
}
impl<'a> Player<'a> {
fn walk(&'a mut self) {
*self.position += 1;
}
}
fn main() {
let mut position = 0;
let mut player = Player::new(&mut position);
loop {
player.walk();
sleep(Duration::from_secs(1));
}
}
Run Code Online (Sandbox Code Playgroud)
错误如下:
error[E0499]: cannot borrow `player` as mutable more than once at a time
--> src/main.rs:30:9
|
30 | player.walk();
| ^^^^^^
| |
| `player` was mutably borrowed here in the previous iteration of the loop
| first borrow used here, in later iteration of loop
Run Code Online (Sandbox Code Playgroud)
我不明白为什么第二个程序在第一个程序编译时无法编译。我知道编译器不接受多个可变借用,但第一个借用不是也是这种情况吗?该程序运行 walk 函数,该函数请求对 self 的可变引用,与第二个程序的方式相同。
在这样的情况下,程序需要借用结构体中的数据,然后修改它,什么被认为是一个好的解决方案?
这是一个常见的错误
impl<'a> Player<'a> {
fn walk(&'a mut self) {
Run Code Online (Sandbox Code Playgroud)
生命的名字是有意义的。由于您在结构和方法中使用相同的生命周期,因此您告诉编译器调用walk借用Player<'a>for 'a,这是借用事物的生命周期Player。因此,您告诉编译器调用此方法借用(可变地,因此不共享)结构的时间超过了结构可以存在的时间,本质上将您自己完全锁定在结构之外。
解决方案很简单,只需删除方法中的一个即可:
impl<'a> Player<'a> {
fn walk(&mut self) {
Run Code Online (Sandbox Code Playgroud)
现在 Rust 可以创建第二个生命周期(您可以显式命名,只要它不是'a),并且它推断该生命周期仅与函数体一样长,因为没有任何逃逸。
事实上,由于您不需要主动使用'a,您也可以不命名它,您仍然必须将其传入,因为它Player在生命周期内是通用的,并且您不能只省略类型参数,但编译器是完美的高兴
impl Player<'_> {
fn walk(&mut self) {
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
87 次 |
| 最近记录: |