I have the following code which fails to compile because it says the borrowed value does not live long enough:
struct Node {
val: RwLock<f32>,
next: RwLock<Option<Arc<Node>>>,
}
impl Node {
pub fn traverse(&self) {
let mut current_node = self;
loop {
let guard = current_node.next.read().unwrap();
let val = &*guard;
{
let next_node = match val {
Some(node) => node,
None => break,
};
println!("{:?}", *current_node.val.read().unwrap());
current_node = next_node;
}
}
}
}
I don't understand why, though. FWIU both guard
and val
are valid for the duration of the scope of the loop iteration. Yet the compiler says:
|
150 | let val = &*guard;
| ^^^^^ borrowed value does not live long enough
...
160 | }
| -
| |
| `guard` dropped here while still borrowed
| borrow might be used here, when `guard` is dropped and runs the `Drop` code for type `RwLockReadGuard`
What exactly is going on? How could the borrow be used when guard is dropped and is there a way to fix this?
I tried to get the guard and the val outside of the loop, and tried to put a scoped block inside, not sure what else to try.
You can resolve this by storing Arc<Self>
in current_node
.
use std::sync::{RwLock, Arc};
struct Node {
val: RwLock<f32>,
next: RwLock<Option<Arc<Node>>>,
}
impl Node {
pub fn traverse(self: Arc<Self>) {
let mut current_node = self;
loop {
current_node = {
let guard = current_node.next.read().unwrap();
println!("{:?}", *current_node.val.read().unwrap());
match &*guard {
Some(node) => Arc::clone(node),
None => break,
}
};
}
}
}