简体   繁体   中英

Obtain a reference from a RefCell<Option<Rc<T>>> in Rust

I am having problem getting a reference out of a RefCell<Option<Rc>>.

Any suggestion?

struct Node<T> {
    value: T
}

struct Consumer3<T> {
    tail: RefCell<Option<Rc<Node<T>>>>,
}

impl<T> Consumer3<T> {
    fn read<'s>(&'s self) -> Ref<Option<T>> {
        Ref::map(self.tail.borrow(), |f| {
            f.map(|s| {
                let v = s.as_ref();
                v.value
            })
        })
    }
}

Gives:

error[E0308]: mismatched types
  --> src/lib.rs:15:13
   |
15 | /             f.map(|s| {
16 | |                 let v = s.as_ref();
17 | |                 v.value
18 | |             })
   | |______________^ expected reference, found enum `Option`
   |
   = note: expected reference `&_`
                   found enum `Option<T>`
help: consider borrowing here
   |
15 |             &f.map(|s| {
16 |                 let v = s.as_ref();
17 |                 v.value
18 |             })
   |

error: aborting due to previous error

Playground

Mapping from one Ref to another requires that the target already exist in memory somewhere. So you can't get a Ref<Option<T>> from a RefCell<Option<Rc<Node<T>>>> , because there's no Option<T> anywhere in memory.

However, if the Option is Some , then there will be a T in memory from which you can obtain a Ref<T> ; if the Option is None , obviously you can't. So returning Option<Ref<T>> may be a viable alternative for you:

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

struct Node<T> {
    value: T
}

struct Consumer3<T> {
    tail: RefCell<Option<Rc<Node<T>>>>,
}

impl<T> Consumer3<T> {
    fn read(&self) -> Option<Ref<T>> {
        let tail = self.tail.borrow();
        
        if tail.is_some() {
            Some(Ref::map(tail, |tail| {
                let node = tail.as_deref().unwrap();
                &node.value
            }))
        } else {
            None
        }
    }
}

Playground .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM