Как я могу соответствовать, не занимая в Rust? - PullRequest
0 голосов
/ 26 января 2019

Я борюсь с заемщиком, пытаясь написать «Игру жизни» Конвея. У меня есть два цикла for, выполняющих изменчивое заимствование для self.cell_states, то есть Vec<Vec<CellState>> (CellState - это перечисление), чтобы я мог обновить статус Alive или Dead каждой ячейки.

Чтобы решить, должна ли клетка быть живой или мертвой, необходимо увидеть, сколько из окружающих клеток живы. Здесь я столкнулся с проблемами. Единственный способ проверить, жива ли ячейка, - это сделать оператор match, но, очевидно, match заимствует значение, что недопустимо, поскольку я уже сделал изменяемый заем. Мне кажется, что я мог просто скопировать значение и проверить скопированное значение, поэтому я попытался match self.cell_states[i+x-1][j+y-1].clone() {...}, но безрезультатно. Как я могу сделать матч без заимствования?

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

Мой код выглядит следующим образом ( Детская площадка ):

#[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,
                        _ => ()
                    }
                }
            }
        }
    }
}

1 Ответ

0 голосов
/ 26 января 2019

Как сопоставить без заимствования в Rust?

Вы не можете.

Каждый раз, когда вы получаете доступ к переменной, выодолжить это.Печать переменной?Это заимствование.Проверка, имеет ли переменная конкретное значение?Заимствование снова.Копирование значения переменной?Также заимствование.

Вы пытаетесь получить доступ к значениям вектора, пока вектор заимствован.Это просто не сработает - заемщик запрещает это.

Можете ли вы обойти это?Да! Обычный трюк при работе с векторами или массивами - задержка всех заимствований путем итерации по индексам.Поэтому напишите что-то вроде этого:

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

В этом случае вектор не заимствован, но вы можете заимствовать его элементы позже, просто проиндексировав его.

Но: заемШашка только что спасла вас, потому что вы пытались глючить! То, что вы пытались, это не то, как работает Game of Life!Вам нужно две сетки ячеек, потому что шаг обновления не может обновить все ячейки на лету.Сначала вы должны вычислить все новые ячейки в новый вектор (чтобы вы могли использовать все старые значения ячеек при расчете новых), а затем вы можете заменить старый вектор новым.Таким образом, этап обновления в Game of Life представляет собой двухэтапный процесс - вы не можете сделать это на месте.

И после исправления этой реальной ошибки вы обнаружите, что не будете сталкиваться с этой конкретной проверкой заимствований.проблема снова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...