我希望有一个名为Factory的struct
,它动态地生成新的Strings
,将它们保存在自己内部,并返回&str
个与Factory Value本身相同生命周期 的borrow .
我试图将新值保持在Vec
以内,但随着Vec
的增长,对元素的borrow 将失效,因此它们的生命周期 不够长.我试着用Boxes
、RefCells
包装它们,但我遇到了同样的问题.
我还想在循环中调用这个工厂方法,这样我就可以在每次迭代中生成新的字符串,并borrow 它来保存在某个地方.
有一个 crate ,叫串口:https://docs.rs/string-interner/latest/string_interner/index.html
如果您想要的只是字符串句柄,那么直接使用它或通过类似的 struct 使用它可能是一个好主意,如下所示.
这就是我到目前为止得到的信息,感谢你们的 comments :
use std::{ cell::{Ref, RefCell}, rc::Rc, };
struct StringHandle {
key: usize,
store: Rc<RefCell<Vec<String>>>,
}
impl StringHandle {
pub fn get(&self) -> Ref<String> {
Ref::map(self.store.borrow(), |v| &v[self.key])
}
}
struct Factory {
pub store: Rc<RefCell<Vec<String>>>,
}
impl Factory {
pub fn make_next_string(&mut self) -> StringHandle {
let len = self.store.borrow().len();
self.store.borrow_mut().push(format!("string no. {}", len));
StringHandle {
store: self.store.clone(),
key: len,
}
}
pub fn new() -> Factory {
Factory { store: Rc::new(RefCell::new(vec![])) }
}
}
let mut f = Factory::new();
let mut strs: Vec<StringHandle> = vec![];
for _ in 0..5 {
let handle = f.make_next_string();
strs.push(handle);
}
for handle in strs {
println!("{}", handle.get());
}
字符串以外的 struct 的泛型版本:
use std::{ cell::{Ref, RefCell, RefMut}, rc::Rc, };
struct Handle<T> {
key: usize,
store: Rc<RefCell<Vec<T>>>,
}
impl<T> Handle<T> {
pub fn get(&self) -> Ref<T> {
Ref::map(self.store.borrow(), |v| &v[self.key])
}
pub fn get_mut(&self) -> RefMut<T> {
RefMut::map(self.store.borrow_mut(), |v| &mut v[self.key])
}
}
struct Factory<T> {
pub store: Rc<RefCell<Vec<T>>>,
}
impl<T: Default> Factory<T> {
pub fn make_next(&mut self) -> Handle<T> {
let len = self.store.borrow().len();
self.store.borrow_mut().push(T::default());
Handle {
store: self.store.clone(),
key: len,
}
}
pub fn new() -> Factory<T> {
Factory { store: Rc::new(RefCell::new(vec![])) }
}
}
#[derive(Debug)]
struct Data {
pub number: i32
}
impl Default for Data {
fn default() -> Self {
Data { number: 0 }
}
}
let mut objs: Vec<Handle<Data>> = vec![];
let mut f: Factory<Data> = Factory::new();
for i in 0..5 {
let handle = f.make_next();
handle.get_mut().number = i;
objs.push(handle);
}
for handle in objs {
println!("{:?}", handle.get());
}