Chciałem dziś zrobić ładnie z .fold()
ale kopiowanie boarda po oznaczeniu pola strasznie się ślimaczyło, a nie umiem przekonać borrow-checkera do jakiegoś:
lines.iter()
.fold(board, |board, line| board.mark_line(line));
ale w sytuacji kiedy mark_line
nie zwraca kopii Board tylko &Board
edit: Żeby wyjaśnić o co pytam. Można by napisać taki kod:
use itertools::Itertools;
struct Board {
board: Vec<i32>,
}
impl Board {
fn new(size: i32) -> Board {
return Board { board: (0..size).map(|x| 0).collect_vec() };
}
fn mark_field(&self, index: usize) -> Board {
return Board {
board: self.board
.iter()
.enumerate()
.map(|(i, &value)| if i == index { value + 1 } else { value })
.collect_vec()
};
}
}
pub(crate) fn solve() {
let board = (0..10000)
.fold(Board::new(10000), |board, index| board.mark_field(index));
println!("{}", board.board[1]);
}
Czyli za każdym razem kiedy robimy mark_field
zwracamy nową planszę. Tylko że jak plansza jest duża to nagle robi sie to bardzo wolne, z oczywistych względów.
I teraz zastanawiałem się, czy można tak zrobić, zeby nasze mark_field
zwracało zmodyfikowaną początkową tablicę, a nie tworzyło nową za każdym razem (pytanie co jest "bardziej rustowe" i moze jest jakaś trzecia opcja?). I pisząc tego posta doszedłem do tego, ze mogę zrobić:
fn mark_field(mut self, index: usize) -> Board {
self.board[index]+=1;
return self;
}
Bo mogę przyjąć sobie self
a nie &self
jako argument.