简体   繁体   中英

'cannot return reference to temporary value' using Option<Rc<RefCell<T>>>

So I have some code like this:

use std::borrow::Borrow;
use std::cell::RefCell;
use std::collections::HashMap;
use std::ops::Index;
use std::rc::Rc;

struct Data {
    // ...
}

struct TableTreeNode {
    father: Option<Rc<RefCell<TableTreeNode>>>,
    table: HashMap<String, Data>,
}

impl Index<&str> for TableTreeNode {
    type Output = Data;

    fn index(&self, index: &str) -> &Self::Output {
        if self.table.contains_key(index) {
            self.table.index(index)
        } else {
            //recursively goes up
            let father: &RefCell<TableTreeNode> = self.father.as_ref().expect("not found");
            father.borrow().index(index)
        }
    }
}

It fails on compile:

error[E0515]: cannot return reference to temporary value
  --> xxx.rs:25:13
   |
25 |             father.borrow().index(index)
   |             ---------------^^^^^^^^^^^^^
   |             |
   |             returns a reference to data owned by the current function
   |             temporary value created here

I have no clue to solve this. How would a borrow from a RefCell could be a temporary variable? If I'm doing this wrong, what's the right way to implement these?

Because RefCell::borrow() returns aRef guard. This guard implements Deref , and when it is dropped it marks the RefCell as no longer borrowed.

Generally, you cannot hide a RefCell across API boundaries if you use it. You have to return a Ref<Something> or RefMut<Something> instead os &[mut] Something . And because the signature of Index is constant and expecting a reference, that means you cannot implement Index .

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