如何从Rc<RefCell<String>>返回&str?解决临时值编译错误
解决Rc<RefCell>返回&str的E0515错误
这个E0515错误的核心问题是:borrow()返回的Ref<String>是临时值,函数执行完就会被销毁,它持有的借用也会跟着释放,导致你返回的&str变成悬空引用——Rust的安全机制直接拦住了这种危险操作。下面给你几种靠谱的修复方式:
方案1:返回Ref,让调用方处理引用
直接把get方法的返回类型改成Ref<String>,这样调用方可以通过as_str()获取&str,同时Ref会一直持有对内部字符串的借用,防止数据被修改或提前释放。
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; } fn get(&self) -> Ref<String> { self.data.borrow() } } 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.as_str()); }
方案2:返回克隆的String
如果不需要保持原数据的引用关系,直接返回内部字符串的克隆版本。这种方式简单直接,但会有字符串复制的开销,适合数据量不大的场景。
use std::rc::Rc; use std::cell::RefCell; struct Data { data: Rc<RefCell<String>> } impl Data { fn set(&mut self, data: String) { *self.data.borrow_mut() = data; } fn get(&self) -> String { self.data.borrow().clone() } } 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); }
方案3:自定义包装类型,兼顾便利性和安全性
如果想要像使用&str一样方便,又不想让调用方直接处理Ref,可以自定义一个包装结构体,内部持有Ref<String>并实现Deref trait,让它能自动解引用成&str。
use std::rc::Rc; use std::cell::{RefCell, Ref}; use std::ops::Deref; struct Data { data: Rc<RefCell<String>> } // 自定义守卫类型,持有Ref<String> struct StrGuard<'a> { inner: Ref<'a, String>, } // 实现Deref,让StrGuard可以像&str一样使用 impl<'a> Deref for StrGuard<'a> { type Target = str; fn deref(&self) -> &Self::Target { self.inner.as_str() } } impl Data { fn set(&mut self, data: String) { *self.data.borrow_mut() = data; } fn get(&self) -> StrGuard<'_> { StrGuard { inner: self.data.borrow(), } } } 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); // 自动解引用为&str }
方案选择建议
- 方案1最贴合Rust的安全设计,零开销,适合需要保持原数据引用的场景;
- 方案2最简单,适合对性能要求不高、数据量小的场景;
- 方案3兼顾了使用便利性和安全性,适合需要频繁以
&str形式使用数据的场景。
内容的提问来源于stack exchange,提问作者alexzander
相关产品推荐
相关产品推荐

