1

im trying to return a &str slice from a String which is behind a an Rc<RefCell<>>

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

struct Data {
    data: Rc<RefCell<String>>
}

impl Data {
    fn set(
        &mut self,
        data: String
    ) {
        *self.data.borrow_mut() = data;
    }

    // TODO: fix here
    fn get(&self) -> &str {
        self.data.borrow().as_str()
    }
}

fn main() {
    let mut data = Data {
        data: Rc::new(RefCell::new(String::new()))
    };
    data.set(String::from("how can i solve this?"));
    let d = data.get();
    println!("{}", d);
}

here's the compilation error

error[E0515]: cannot return reference to temporary value
  --> questions/refcell-data-inspection/src/main.rs:21:9
   |
21 |         self.data.borrow().as_str()
   |         ------------------^^^^^^^^^
   |         |
   |         returns a reference to data owned by the current function
   |         temporary value created here

well, i understand its a temporary value crated because borrow returns a guard, which will go out of scope.

how can i fix this in order to return a &str slice from that String?

alexzander
  • 1,586
  • 1
  • 9
  • 21

1 Answers1

0

Well, as you said yourself "borrow guard" will be out of scope at the one of a function, so you cannot do that. Think of it that way. If you managed to return a reference into String, how would RefCell know that this reference exists and that it cannot give for example a mutable reference.

Only thing that you can do is to return that guard. This would mean, that you must change function's signature, but it will be as usable as a &str would be. So try this:

fn get(&self) -> Ref<'_, String> {
    self.data.borrow()
}

EDIT. You might want to also look at that question: How to borrow the T from a RefCell<T> as a reference?

Aleksander Krauze
  • 3,115
  • 7
  • 18
  • 1
    I would add that if you want to return a reference to a part of the string instead of the whole string, you can use [`Ref::map`](https://doc.rust-lang.org/1.54.0/std/cell/struct.Ref.html#method.map) like: `Ref::map (self.data.borrow(), |s| s.trim())` (`trim` is only an example of an operation returning a substring). – Jmb Oct 14 '22 at 14:47