I try to solve https://adventofcode.com/ using Rust to reactivate and improve my skills. Today I ran into an issue with the borrow checker which I did not understand. I spend hours trying to understand what's happening and the following code is the smallest minimal example I could come up with.
struct Map {}
#[derive(Clone, Copy)]
struct Pos<'a> {
x: usize,
y: usize,
m: &'a Map
}
impl<'a> Pos<'a> {
fn move_into(&self, _direction: &str) -> Option<Pos> {
Some(
Pos{
x:self.x+1,
y:self.y+1,
m:self.m
}
)
}
}
fn walk(start: &Pos) -> bool {
let mut current = (*start).clone();
for idx in 0..3 {
current = match current.move_into("x") {
Some(next) => {
if next.x == 2 {
return true;
}
next
},
None => { return false; }
};
}
false
}
fn main() {
let m = Map{};
let pos = Pos{x:0, y:0, m: &m};
walk(&pos);
}
The borrow checker complains about the current = match current.move_into ...
in the walk
function and tells me, that I cannot do that because current
is borrowed. The following code has Map
and related lifetimes removed. Otherwise it is the same.
#[derive(Clone, Copy)]
struct Pos {
x: usize,
y: usize,
}
impl Pos {
fn move_into(&self, _direction: &str) -> Option<Pos> {
Some(
Pos{
x:self.x+1,
y:self.y+1,
}
)
}
}
fn walk(start: &Pos) -> bool {
let mut current = (*start).clone();
for idx in 0..3 {
current = match current.move_into("x") {
Some(next) => {
if next.x == 2 {
return true;
}
next
},
None => { return false; }
};
}
false
}
fn main() {
let pos = Pos{x:0, y:0};
walk(&pos);
}
This code is ok and works. I don't have the slightest idea how the lifetime / reference in the struct affects the borrowing in my function. Could somebody please explain to me what's going on here?