rust - 遍历中RefCell的循环引用借用

标签 rust smart-pointers lifetime borrowing interior-mutability

我正在学习 Rust 并尝试编写一个双向链表。但是,我已经陷入了典型的迭代遍历实现。我的印象是借用检查器/丢弃检查器过于严格,当它从 RefCell 跨越函数边界时无法推断出借用的正确生命周期。我需要重复设置变量绑定(bind)(在本例中为 curr)以借用其当前内容:

use std::cell::RefCell;
use std::rc::Rc;

pub struct LinkedList<T> {
    head: Option<Rc<RefCell<LinkedNode<T>>>>,
    // ...
}

struct LinkedNode<T> {
    value: T,
    next: Option<Rc<RefCell<LinkedNode<T>>>>,
    // ...
}

impl<T> LinkedList<T> {
    pub fn insert(&mut self, value: T, idx: usize) -> &mut LinkedList<T> {
        // ... some logic ...

        // This is the traversal that fails to compile.
        let mut curr = self.head.as_ref().unwrap();
        for _ in 1..idx {
            curr = curr.borrow().next.as_ref().unwrap()
        }

        // I want to use curr here.
        // ...
        unimplemented!()
    }
}

编译器提示:

没有 NLL

error[E0597]: borrowed value does not live long enough
  --> src/lib.rs:22:20
   |
22 |             curr = curr.borrow().next.as_ref().unwrap()
   |                    ^^^^^^^^^^^^^ temporary value does not live long enough
23 |         }
   |         - temporary value dropped here while still borrowed
...
28 |     }
   |     - temporary value needs to live until here
   |
   = note: consider using a `let` binding to increase its lifetime

使用 NLL

error[E0716]: temporary value dropped while borrowed
  --> src/lib.rs:22:20
   |
22 |             curr = curr.borrow().next.as_ref().unwrap()
   |                    ^^^^^^^^^^^^^
   |                    |
   |                    creates a temporary which is freed while still in use
   |                    a temporary with access to the borrow is created here ...
23 |         }
   |         -
   |         |
   |         temporary value is freed at the end of this statement
   |         ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `std::cell::Ref<'_, LinkedNode<T>>`
   |
   = note: consider using a `let` binding to create a longer lived value
   = note: The temporary is part of an expression at the end of a block. Consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped.

我真的很感激这个问题的迭代解决方案(非递归)。

最佳答案

您可以克隆 Rc 以避免生命周期问题:

let mut curr = self.head.as_ref().unwrap().clone();
for _ in 1..idx {
    let t = curr.borrow().next.as_ref().unwrap().clone();
    curr = t;
}

关于rust - 遍历中RefCell的循环引用借用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36597987/

相关文章:

rust - Rust 中的 "Subclassing"特征

macros - 是否可以定义一个处理语法情况的宏?

pointers - 为什么指向堆上某物的指针的大小大于堆栈变量的大小?

c++ - 我怎么知道谁拥有某个指针

rust - 如何在不必处理生命周期的情况下存储引用?

ubuntu - 为什么 Rust 编译器不能从拆分标准输入行中推断出来

rust - 分配的匿名与结构生命周期

c++ - 为什么 std::unique_ptr 有一个相等运算符?

rust - 预期绑定(bind)生命周期参数,在尝试传递 Option<FnOnce> 时找到具体生命周期

c++ - 使用指针显式调用指向对象的析构函数后,指针持有什么样的值?