Return 引用 Rc 中的内容<RefCell<>> 没有 Ref::map

Return Ref to something inside of Rc<RefCell<>> without Ref::map

首先是工作代码:

use std::cell::{Ref, RefCell};
use std::rc::Rc;

struct ValueHolder {
    value: i32
}

fn give_value(wrapped: &Rc<RefCell<ValueHolder>>) -> Ref<i32> {
    Ref::map(
        (**wrapped).borrow(),
        |borrowed| { &(*borrowed).value },
    )
}

fn main() {
    println!("Our value: {}", *give_value(
        &Rc::new(RefCell::new(ValueHolder { value: 1337 }))
    ));
}

相关部分是 give_value 函数。

我想 return 一个 Ref 到一个 Rc<RefCell<>> 里面的东西,在这个例子中是一个结构里面的值。

效果很好,但由于我刚开始学习 Rust,我想知道,如果不使用 Ref::map

我怎么能达到同样的效果

“幼稚”的方法:

fn give_value(wrapped: &Rc<RefCell<ValueHolder>>) -> &i32 {
    &(*(**wrapped).borrow()).value
}

由于显而易见的原因而失败:

error[E0515]: cannot return value referencing temporary value
 --> src/bin/rust_example.rs:9:5
  |
9 |     &(*(**wrapped).borrow()).value
  |     ^^^--------------------^^^^^^^
  |     |  |
  |     |  temporary value created here
  |     returns a value referencing data owned by the current function

所以我的问题是:如何自己重新创建 Ref::map 函数的功能?

你不能。 RefCell 要求在使用该值时使用 Ref,因此它知道何时应该允许借用。当 Ref 被删除时,它向 RefCell 发出信号,表明它可以减少借用计数,如果借用计数为 0,则可能发生可变借用。能够获得对不借用 Ref 的内部数据的引用(请注意,您可以从函数 return 引用不能借用 Ref 否则您将引用一个临时的)会有问题,因为这样 Ref 可能会被删除并且 RefCell 认为它可以借出一个可变的借用,但仍然存在对数据的不可变借用。 Ref::map 的源代码是:

pub fn map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Ref<'b, U>
where
    F: FnOnce(&T) -> &U,
{
    Ref { value: f(orig.value), borrow: orig.borrow }
}

其中使用了您无法访问的私有字段。所以,不,你不能自己重新创建 Ref::map