在 RwLock 上迭代时,Rust“借用的价值不够长”

问题描述 投票:0回答:1

我有以下代码无法编译,因为它说借来的价值不够长:

        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;
                    }
                }
            }
        }

虽然我不明白为什么。 FWIU

guard
val
在循环迭代范围内有效。然而编译器说:

    |
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`

到底是怎么回事?当守卫被撤职时如何使用借用,有没有办法解决这个问题?

我试图让 guard 和 val 在循环之外,并试图在里面放一个作用域块,不知道还能尝试什么。

rust borrow-checker rwlock
1个回答
0
投票

您可以通过将

Arc<Self>
存储在
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,
                }
            };
        }
    }
}

游乐场

© www.soinside.com 2019 - 2024. All rights reserved.