首页 > 解决方案 > 将 Ref 返回到 Rc 内部的东西> 没有 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功能。

我想将 a 返回Ref到 a 内的某个东西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功能?

标签: rustownershipborrowingrefcell

解决方案


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


推荐阅读