我必须遍历键,通过键在HashMap中找到值,可能在找到的结构中做一些繁重的计算来作为一个值(惰性=>改变结构),并缓存在Rust中返回它。
我收到以下错误消息:
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> src/main.rs:25:26
|
23 | fn it(&mut self) -> Option<&Box<Calculation>> {
| - let's call the lifetime of this reference `'1`
24 | for key in vec!["1","2","3"] {
25 | let result = self.find(&key.to_owned());
| ^^^^ `*self` was mutably borrowed here in the previous iteration of the loop
...
28 | return result
| ------ returning this value requires that `*self` is borrowed for `'1`
use std::collections::HashMap;
struct Calculation {
value: Option<i32>
}
struct Struct {
items: HashMap<String, Box<Calculation>> // cache
}
impl Struct {
fn find(&mut self, key: &String) -> Option<&Box<Calculation>> {
None // find, create, and/or calculate items
}
fn it(&mut self) -> Option<&Box<Calculation>> {
for key in vec!["1","2","3"] {
let result = self.find(&key.to_owned());
if result.is_some() {
return result
}
}
None
}
}
self
和结构),因为可能的计算会改变它关于如何更改设计的任何建议(因为Rust会以有意义的方式进行一些不同的思考)或解决该问题?
PS。该代码还有其他一些问题,但让我们分解问题,然后首先解决这个问题。
您不能使用独占访问进行缓存。您不能将Rust引用像通用指针一样对待(顺便说一句,&String
并且&Box<T>
是双重间接的,并且在Rust中非常单一。使用&str
或&T
用于临时借用)。
&mut self
意味着不仅可变,而且互斥和可变,因此您的缓存仅支持返回一项,因为它返回的引用必须保持self
“锁定”状态。
您需要说服借阅检查器,find
下次调用它时返回的东西不会突然消失。当前还没有这样的保证,因为该接口不会阻止您调用例如items.clear()
(借阅检查器会检查该函数的接口允许的功能,而不是检查实际功能的功能)。
您可以通过使用Rc
或使用实现内存池/舞台的板条箱来实现。
struct Struct {
items: HashMap<String, Rc<Calculation>>,
}
fn find(&mut self, key: &str) -> Rc<Calculation>
这样,如果您克隆Rc
,它将在不需要缓存的情况下长期生存。
您还可以使其内部可变性更好。
struct Struct {
items: RefCell<HashMap<…
}
这将使您的记忆find
方法可以使用共享借阅而不是互斥借阅:
fn find(&self, key: &str) -> …
对于该方法的调用者而言,使用起来要容易得多。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句