You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建可动态生成值并返回其借用的Factory结构体?

问题描述

我需要一个名为Factory的结构体,它要能动态生成新的String,将这些字符串存储在内部,并且返回与Factory自身生命周期一致的&str借用。

我曾尝试用Vec存储这些新值,但Vec扩容时元素的借用会失效,导致生命周期不足;也试过用Box、RefCell包装,还是遇到同样的问题。另外,我希望能在循环中调用该工厂的方法,每次迭代生成新的String并保留其借用。


解决方案

有一个string-interner crate,如果你的需求只是获取字符串句柄,直接使用它或者参考下面的类似结构体实现都是不错的选择。

针对String的实现

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());
}

适用于任意结构体的泛型版本

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());
}

内容的提问来源于stack exchange,提问作者Kamil Szot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 23:50:41