Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 返回一个Vec<&;str>;从参照单元格<;Vec<;字符串>>;?(或替代方法?)_Rust - Fatal编程技术网

Rust 返回一个Vec<&;str>;从参照单元格<;Vec<;字符串>>;?(或替代方法?)

Rust 返回一个Vec<&;str>;从参照单元格<;Vec<;字符串>>;?(或替代方法?),rust,Rust,所以我有一种数据库结构,它为我的应用程序存储数据。当数据变脏时,它会从数据库中获取数据并将其存储在结构中。无论哪种方式,当请求此数据时(Vec),我们将在数据库结构中的某个位置存储一个现有的字符串 从外部看,它应该看起来像这个数据库本身并没有发生变化,因为它应该看起来只是从数据库中获取数据。然而,在内部,它实际上存储了一些缓存,这样就不必在每一帧都获取数据。因此,我使用RefCell来存储缓存 好的,现在我应该能够得到一个Vec,其中&str引用了存储在数据库结构中的字符串 但是,不能保证此缓存

所以我有一种数据库结构,它为我的应用程序存储数据。当数据变脏时,它会从数据库中获取数据并将其存储在结构中。无论哪种方式,当请求此数据时(
Vec
),我们将在数据库结构中的某个位置存储一个现有的
字符串

从外部看,它应该看起来像这个数据库本身并没有发生变化,因为它应该看起来只是从数据库中获取数据。然而,在内部,它实际上存储了一些缓存,这样就不必在每一帧都获取数据。因此,我使用
RefCell
来存储缓存

好的,现在我应该能够得到一个
Vec
,其中
&str
引用了存储在数据库结构中的
字符串

但是,不能保证此缓存始终存在。例如,当数据无效时,需要再次获取数据。实际上,我们有一个
RefCell

使用std::cell::RefCell;
结构连接{}
发布结构数据库{
db:连接,
项目\u缓存:RefCell,
// ...
}
不幸的是,我似乎无法做到这一点:

impl数据库{
发布fn项目(&self)->结果{
if self.projects\u cache.borrow()是\u some(){
让缓存:&Vec=&*self.projects\u cache.borrow().as\u ref().unwrap();
返回Ok(cached.iter().map(| name | name.as_str()).collect());
}
//如果没有,则从数据库获取数据并将其存储在缓存中
// ...
未执行!()
}
}
显然,这是一个临时值

错误[E0515]:无法返回引用临时值的值
-->src/lib.rs:15:20
|
14 |让缓存:&Vec=&*self.projects_cache.borrow().as_ref().unwrap();
|------------------------------此处创建的临时值
15 |返回Ok(cached.iter().map(| name | name.as_str()).collect());
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^返回引用当前函数拥有的数据的值
所以我的问题是:

  • 为什么这个值是暂时的?
    字符串存在。我们只是想参考一下。那么为什么这是暂时的呢

  • 我如何习惯性地做这件事?我一点也不喜欢这种方法。我所关心的是:我可以存储缓存;fetch函数接受
    &self
    ,从外部看是不可变的;而且,出于性能原因,我不必为每一帧制作全新的
    String


  • RefCell
    可以通过共享引用进行变异,因为它执行运行时检查-通过内部跟踪对它的活动引用数(引用计数),确保没有使用任何其他引用

    这是通过
    Ref
    结构实现的-只要它存在,您就可以通过它读取
    RefCell
    的内容。它的析构函数递减引用计数,通知
    RefCell
    它将不再使用

    这就是为什么您不能为用户提供对
    RefCell
    内容的正常引用(
    &str
    )-没有什么可以阻止它允许其内容发生变异。在这种情况下,
    字符串
    将存在的承诺仅在
    Ref
    在范围内时有效

    但是,您可以将
    Ref
    封装为实现细节。通过将
    Ref
    包装在
    项目
    类型中,您可以让用户与更简单的API交互:

    pub结构项目);
    
    impl项目谢谢你的建议-是的,但也不是。我以前看过这篇文章,但它没有让我满意。这个解决方案很难看,它让我觉得这不是最佳解决方案。我更感兴趣的是一种更惯用的方法可能是什么样子,不管它是否像这样使用
    RefCell
    。上面的答案返回一些自定义结构,下一个返回一些
    Ref
    struct。我想完全隐藏这个
    RefCell
    实现,所以。最后,我还询问了为什么这个值被认为是临时的,但在这个线程中没有回答。我觉得您没有试图理解
    Ref
    为什么在这里很重要。正如错误消息所示,
    Ref
    是临时的(请注意,它在整个表达式
    self.projects\u cache.borrow()
    下面加下划线)
    Ref
    RefCell
    在运行时跟踪借用的方式。如果您可以返回
    Vec
    RefCell
    将无法知道原始
    选项何时不再被借用(请注意,您实际上可以在夜间使用时安全地执行此操作,但这样做意味着您再也不能
    借用了)。谢谢!有没有更惯用的方法?尽管开销很大,但返回克隆是否更合适?理想情况下,我希望这在功能上等同于读取不可变结构的字段,就好像该字段一直存在一样。