简体   繁体   English

如果不借用Rust,我该怎么匹配?

[英]How can I match without borrowing in Rust?

I'm wrestling with the borrow checker while trying to write Conway's Game of Life. 在尝试撰写康威的生命游戏时,我正在与借阅检查员搏斗。 I have two for loops doing a mutable borrow on self.cell_states , which is a Vec<Vec<CellState>> ( CellState is an enum) so that I can update the Alive or Dead status of each cell. 我有两个for循环在self.cell_states上进行可变借用,这是一个Vec<Vec<CellState>>CellState是一个枚举),这样我就可以更新每个单元格的AliveDead状态。

In order to decide if a cell should be alive or dead though, it needs to see how many of the surrounding cells are alive. 为了确定一个细胞是否应该存活或死亡,它需要看到有多少周围细胞存活。 This is where I've run into problems. 这是我遇到问题的地方。 The only way I can find to check if a cell is alive is to do a match statement, but apparently match borrows the value, which is not allowed, since I've already done a mutable borrow. 我可以找到检查单元格是否存活的唯一方法是执行match语句,但显然match借用了值,这是不允许的,因为我已经完成了可变的借位。 It seems to me that I could just copy the value and check against the copied value, so I tried match self.cell_states[i+x-1][j+y-1].clone() {...} , but to no avail. 在我看来,我可以复制值并检查复制的值,所以我尝试match self.cell_states[i+x-1][j+y-1].clone() {...} ,但无济于事。 How can I do a match without borrowing? 如何在不借用的情况下进行比赛?

error[E0502]: cannot borrow `cell_states` as immutable because it is also borrowed as mutable
  --> src/main.rs:18:27
   |
11 |     for (i, row) in cell_states.iter_mut().enumerate() {
   |                     ----------------------------------
   |                     |
   |                     mutable borrow occurs here
   |                     mutable borrow used here, in later iteration of loop
...
18 |                     match cell_states[i+x-1][j+y-1] {
   |                           ^^^^^^^^^^^ immutable borrow occurs here

My code is as follows ( Playground ): 我的代码如下( 游乐场 ):

#[derive(Copy, Clone)]
pub enum CellState {
    Dead,
    Alive
}

fn main() {
    let mut cell_states = vec![vec![CellState::Dead; 10]; 10];


    for (i, row) in cell_states.iter_mut().enumerate() {
        for (j, cell) in row.iter_mut().enumerate() {
            // Count the living cells around cell
            let mut count = 0;

            for x in 0..3 {
                for y in 0..3 {
                    match cell_states[i+x-1][j+y-1] {
                        CellState::Alive => count += 1,
                        _ => ()
                    }
                }
            }
        }
    }
}

How can I match without borrowing in Rust? 如果不借用Rust,我该怎么匹配?

You can't. 你不能。

Every time you access a variable, you are borrowing it. 每次访问变量时,都要借用它。 Printing a variable? 打印变量? That's borrowing. 这是借来的。 Checking if the variable has a specific value? 检查变量是否具有特定值? Borrowing again. 再借一次。 Copying the value of a variable? 复制变量的值? Also borrowing. 也借。

You are trying to access values of the vector while the vector is mutably borrowed. 您正试图在向量可变地借用时访问向量的值。 This just won't work -- the borrow checker forbids this. 这只是行不通 - 借用检查员禁止这样做。

Can you work around this? 你能解决这个问题吗? Yes! 是! The usual trick when working with vectors or arrays is to delay all borrows by iterating over the indices instead. 使用向量或数组时,通常的技巧是通过迭代索引来延迟所有借用。 So write something like this: 所以写这样的东西:

for i in 0..cell_states.len() {
    for j in 0..cell_states[i].len() {
        ...
    }
}

The vector is not borrowed in that case, but you can borrow elements of it later by just indexing it. 在这种情况下,向量不会被借用,但您可以稍后通过索引来借用它的元素。

But: the borrow checker just saved you, because what you attempted was buggy! 但是:借用检查员只是拯救了你,因为你的尝试是错误的! What you tried is not how Game of Life works! 你尝试的不是生命游戏的运作方式! You need two grids of cells, because the update step cannot update all cells on the fly. 您需要两个网格单元格,因为更新步骤无法动态更新所有单元格。 You first have to calculate all new cells into a new vector (so that you can use all the old cell values while calculating the new ones) and then you can replace the old vector with the new one. 首先必须将所有新单元格计算为新向量(以便在计算新单元格时可以使用所有旧单元格值),然后可以用新单元格替换旧单元格。 So the update step in Game of Life is a two step process -- you cannot do it in-place. 因此,Game of Life中的更新步骤是一个两步过程 - 您无法就地执行此操作。

And after fixing that real bug, you will find that you won't run into this specific borrow checker problem again. 在修复了这个真正的bug之后,你会发现你不会再遇到这个特定的借用检查器问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 代码无需借用即可工作,但我无法通过借用使其工作 - Code works without borrowing but I can't make it work with borrowing 为什么 Rust 在 match 语句后仍然借用? - Why is Rust still borrowing after a match statement? Rust 使用变量而不在线程中借用或克隆它 - Rust using variable without borrowing or cloning it in thread 如何避免在 Rust 中同时进行可变和不可变借用? - How to avoid simultaneous mutable and immutable borrowing in Rust? 如何通过 Rust 中的借款正确管理所有权? - How to manage properly ownership with borrowing in Rust? 如何匹配Rust中的单个条件; '匹配','如果匹配,'? 还是“如果让”? - How can I match a single condition in Rust; 'match', 'if matches!', or 'if let'? Rust:我可以通过在较小的 scope 中以简单的方式借用整个固定大小的数组来获得固定大小的切片吗 - Rust: can I have a fixed size slice by borrowing the whole fixed size array in a smaller scope in a simple way 将字符串转换为 &amp;str Rust 而不会导致借用问题 - Converting a String to an &str Rust without resulting in borrowing problem Rust - 从方法中获取值而不借用(计算文件的行数) - Rust - Get value from method without borrowing (count the lines of file) 使用Rust和match语句如何分配TcpListener? - Using Rust and the match statement how can I assign a TcpListener?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM