I've been playing around with Day 5 of advent of code and got everything working.
But I ran into an error when I was doing some debugging.
error[E0502]: cannot borrow `unum` as immutable because it is also borrowed as mutable
--> day5/src/main.rs:25:17
|
20 | .map(|line| {
| ------ mutable borrow occurs here
21 | // im lazy so remember to delete any new lines that come after the update arrays
22 | unum += 1;
| ---- first borrow occurs due to use of `unum` in closure
...
25 | .filter(|update: &Vec<usize>| {
| ------ ^^^^^^^^^^^^^^^^^^^^^ immutable borrow occurs here
| |
| mutable borrow later used by call
...
36 | .expect(format!("Failed on vec: {:?} @ Line: {unum}", update).as_str());
| ---- second borrow occurs due to use of `unum` in closure
I was trying to keep track of the # of update arrays that have been processed and which line caused a panic when unwrapping the first item of the array. This is what unum
is used for.
Here we see I have a mutable ref to unum
where I am incrementing it for each line.
Then I try to print it, when my expect statement is triggered, on creation of temp
.
I know rust borrow rules don't like to have a mut ref
alive while an immut ref
is.
Yet I don't see how this specific scenario can be problematic, given that it is executed on 1 thread.
The idea here being that unum
is incremented for each line, but that ref goes out of scope, once Vec::from_iter(...)
finishes. And after that an immutable ref of unum
is alive only within the scope of the filter(|update| ...)
which finishes before running the next iteration of map
.
Shouldn't the &mut unum
die before the &unum
is made, and the &unum
then dies before the next iteration of &mut unum
?
I'm aware that the issue is the &mut unum
of unum
is being captured within the closure of filter
which then uses the &unum
to print but I don't know if there is anyway to customize this behavior. I am curious what the rusty way to solve this is. Lmk what you guys think.
let mut unum = 0 as usize;
let updates: Vec<Vec<usize>> = i
.map(|line| {
// im lazy so remember to delete any new lines that come after the update arrays
unum += 1;
Vec::from_iter(line.split(",").filter_map(|item| item.parse().ok()))
}) // get all the updates from file
.filter(|update: &Vec<usize>| {
// filter remove bad arrays
//for each element of update
//check if curr elm is a key
//if last elm is inside the mapping for current key then we have bad news
// stop checking array once we find a rule break
// return otherwise
let mut v = update.iter();
let mut is_valid: bool = true;
let mut temp = v
.next()
.expect(format!("Failed on vec: {:?} @ Line: {unum}", update).as_str());
v.for_each(|num| {
if matches!(
page_rules
.get(num)
.and_then(|rules| Some(rules.contains(temp))),
Some(true)
) {
is_valid = false;
return (); // match page rules violated
}
temp = num
});
is_valid
})
.collect();