2015-09-13 3 views
0

У меня такое ощущение, что моя реализация слишком громоздка, и я думаю, что есть лучший способ реализовать эту простую вещь.Найти и нажимать элемент в векторе тем же способом

У меня есть структура Grid, представляющая игровое поле. У меня есть способ добавить ячейку в сетку, этот метод (add_cell) проверяет, существует ли ячейка в сетке перед ее добавлением.

struct Cell { 
    // A simplified version with only one coordinate 
    position: i8, 
} 

struct Grid { 
    // List of cells in the grid 
    cells: Vec<Rc<Cell>>, 
} 

impl Grid { 
    // Add a cell in to the grid 
    pub fn add_cell(&mut self, cell: Cell) { 
     let is_not_yet_in; 
     { 
      if self.cells.iter().find(|&c| c.position == cell.position).is_some() { 
       is_not_yet_in = false; 
      } else { 
       is_not_yet_in = true; 
      } 
     } 
     if is_not_yet_in { 
      self.cells.push(Rc::new(cell).clone()); 
     } 
    } 
} 

Я положил сферу поддельные, после is_not_yet_in декларации, с тем чтобы избежать компиляции ошибки на изменяемом/неизменного заимствования self.cells. Во всяком случае, я думаю, что этот трюк может избежать использования другого подхода.

+0

Удаление видимости после объявления [не имеет] (http://is.gd/kI9O3U) имеет какие-либо ошибки ...? – Shepmaster

ответ

4

Вы должны прочитать и зафиксировать в памяти методы Iterator trait. В частности, вы хотите any здесь. Я также перевернул полярность на имя переменной, чтобы она соответствовала.

pub fn add_cell(&mut self, cell: Cell) { 
    let is_present = self.cells.iter().any(|c| c.position == cell.position); 
    if !is_present { 
     self.cells.push(Rc::new(cell).clone()); 
    } 
} 

Кроме того, Rc::new(cell).clone() не имеет никакого смысла - вы можете также сократить его Rc::new(cell).

+0

Хорошо! Спасибо. Поэтому я предполагаю, что это поведение связано с тем, как работают итераторы (ленивая оценка), правильно? Из-за этого, если я пишу 'let ... = self.cells.iter(). Find (...). Is_some()' он также работает. –

Смежные вопросы