Hello,
Consider this code:
fn borrow_one_or_another<'a>(vec : &'a mut Vec<String>, index : usize) -> &'a mut String {
if let Some(value_a) = vec.get_mut(index) {
return value_a
} else {
if let Some(value_b) = vec.get_mut(index+1) {
return value_b
} else {
panic!("")
}
}
}
fn main() {
let mut myvec = vec!["one".to_string(), "two".to_string(), "three".to_string()];
println!("{}", borrow_one_or_another(&mut myvec, 0))
}
So I imagine the compiler complains about double-borrowing because the result from the first get_mut
isn't dropped until after the whole conditional, including the else clause. So it's perfectly reasonable to complain about the double-borrow here.
But what about this?
fn borrow_one_or_another<'a>(vec : &'a mut Vec<String>, index : usize) -> &'a mut String {
let returned_option = vec.get_mut(index);
if let Some(value_a) = returned_option {
return value_a
}
drop(returned_option);
if let Some(value_b) = vec.get_mut(index+1) {
return value_b
} else {
panic!("")
}
}
It seems that the return value has the effect of borrowing the argument until the end of the function, even though that code path is exclusive with the continuation of the function. What's going in here? Or more interestingly, what is the most elegant work-around**?
**For this case, I know I could use a non-borrowing function like contains()
so I only needed to make one call to get_mut()
in this particular case, but my use of a Vec was to illustrate the compiler's behavior and the "check in advance with non-borrowing functions" strategy isn't a generalizable solution.
Thanks in advance for any insight.