gpt4 book ai didi

rust - Rust中的“cannot return value referencing temporary value”和内部可变性

转载 作者:行者123 更新时间:2023-12-03 11:43:54 24 4
gpt4 key购买 nike

我在Rust中有以下代码:

pub struct RegExpFilter {
...
regexp_data: RefCell<Option<RegexpData>>,
...
}

struct RegexpData {
regexp: regex::Regex,
string: String
}

...
pub fn is_regexp_compiled(&self) -> bool {
self.regexp_data.borrow().is_some()
}

pub fn compile_regexp(&self) -> RegexpData {
...
}

fn regexp(&self) -> &regex::Regex {
if !self.is_regexp_compiled() { // lazy computation that mutates the struct
self.regexp_data.replace(Some(self.compile_regexp()));
}
&self.regexp_data.borrow().as_ref().unwrap().regexp
}

pub fn matches(&self, location: &str) -> bool {
self.regexp().find(location)
}
正则表达式是惰性计算的,捕获了我不想要的 &mut self,因此使用了 RefCell
我收到以下消息:
               &self.regexp_data.borrow().as_ref().unwrap().regexp
| ^-------------------------^^^^^^^^^^^^^^^^^^^^^^^^^
| ||
| |temporary value created here
| returns a value referencing data owned by the current function
编译器消息似乎很清楚: Refborrow()临时创建并返回到外部。但是我相信 Option( self.regexp_data)由structt本身拥有的 RefCell拥有,因此在内部使用它应该没问题(因为该函数不是 pub)。
我也尝试了以下操作(但失败并显示相同的消息)
    fn regexp(&self) -> impl Deref<Target = regex::Regex> + '_ {
if !self.is_regexp_compiled() {
self.regexp_data.replace(Some(self.compile_regexp()));
}
Ref::map(self.regexp_data.borrow(), |it| &it.unwrap().regexp)
}
我该如何解决?

最佳答案

您可以通过使用Ref::map来将.as_ref()转换为&Option<_>来修复Option<&_>版本,以作为引用进行解包:

fn regexp(&self) -> impl Deref<Target = regex::Regex> + '_ {
if !self.is_regexp_compiled() {
self.regexp_data.replace(Some(self.compile_regexp()));
}
Ref::map(self.regexp_data.borrow(), |it| &it.as_ref().unwrap().regexp)
// ^^^^^^^^
}

在这种情况下,我建议使用 once_cell crate 中的 OnceCell:
use once_cell::sync::OnceCell;

pub struct RegexpData {
regexp: regex::Regex,
string: String,
}

pub struct RegExpFilter {
regexp_data: OnceCell<RegexpData>,
}

impl RegExpFilter {
pub fn compile_regexp(&self) -> RegexpData {
unimplemented!()
}

fn regexp(&self) -> &regex::Regex {
&self.regexp_data.get_or_init(|| self.compile_regexp()).regexp
}
}
您可以简单地使用 get_or_init获得相同的效果。 OnceCellLazy(位于同一 crate 中)对于延迟求值非常方便。
playground上看到它。

关于rust - Rust中的“cannot return value referencing temporary value”和内部可变性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66222370/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com