我正在尝试用Rust编写俄罗斯方块游戏。在这个项目中,我有一些结构体,虽然它们会发生变化,但我希望将它们视为不可变的。
我采用的方法是:
#[derive(Debug)]
struct Example {
foo: i8
}
impl Example {
fn change(mut self) -> Self {
self.foo = 8;
self
}
}
这使您可以做出如下操作:
let first = Example { foo: 0 };
let second = first.change();
println!("{:?}", second); // Example { foo: 8 }
但是当你做这样的事情时,它会对你大喊大叫:
let first = Example { foo: 0 };
let second = first.change();
println!("{:?}", first); // error[E0382]: borrow of moved value: `first`
我感到困惑的是,为什么这个代码可以运行:
#[derive(Debug)]
struct Matrix {
cells: [[char; 2]; 2]
}
impl Matrix {
fn new() -> Self {
Matrix {
cells: [['░'; 2]; 2]
}
}
fn solidify(mut self, row: usize, column: usize) -> Self {
self.cells[row][column] = '█';
self
}
}
fn main() {
let matrix = Matrix::new();
let matrix = matrix.solidify(0, 0);
println!("{:?}", matrix); // Matrix { cells: [['█', '░'], ['░', '░']] }
}
当这个不是这样的时候?
#[derive(Debug)]
struct Matrix {
cells: [[char; 2]; 2]
}
impl Matrix {
fn new() -> Self {
Matrix {
cells: [['░'; 2]; 2]
}
}
fn solidify(mut self, row: usize, column: usize) -> Self {
self.cells[row][column] = '█';
self
}
}
#[derive(Debug)]
struct Tetris {
matrix: Matrix
}
impl Tetris {
fn new() -> Self {
Tetris {
matrix: Matrix::new()
}
}
fn change(&mut self) {
self.matrix = self.matrix.solidify(0, 0);
/* -----------------------------------------
This is where it yells at me ^ */
}
}
fn main() {
let mut tetris = Tetris::new();
tetris.change();
println!("{:?}", tetris); // error[E0507]: cannot move out of `self.matrix` which is behind a mutable reference
}
这将会得到:
error[E0507]: cannot move out of `self.matrix` which is behind a mutable reference
--> src/main.rs:32:23
|
32 | self.matrix = self.matrix.solidify(0, 0);
| ^^^^^^^^^^^ -------------- `self.matrix` moved due to this method call
| |
| move occurs because `self.matrix` has type `Matrix`, which does not implement the `Copy` trait
|
note: `Matrix::solidify` takes ownership of the receiver `self`, which moves `self.matrix`
--> src/main.rs:13:21
|
13 | fn solidify(mut self, row: usize, column: usize) -> Self {
| ^^^^
我做了一些研究,感觉std::mem::swap、std::mem::take或std::mem::replace可以帮我解决问题,但我不太确定该怎么做。
&mut self
来获取self的可变引用,而不是使用mut self
,并且在solidify
和Example::change
中都不返回任何内容。如果你还没有阅读所有权这一章节,我建议你现在就去阅读一下。 - cafce25&mut
引用获取self
时,如何从solidify
返回self
? 编译器提示错误,显示“期望结构体Matrix,发现&mut Matrix”。 - eliaxelang007