我正试着用铁 rust 来写俄罗斯方块.我在这个项目中有一些 struct ,我想将其视为immutable个,即使它们发生了do个Mutations .
我用来实现这种行为的方法是:
#[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 mut matrix = Matrix::new();
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::交换、Std::Mem::Take或STD::Mem::Replace、
可以为我做这个戏法,但我不确定是怎么做的.