gpt4 book ai didi

rust - Entry::Occupied.get() 返回一个引用当前函数拥有的数据的值,即使 hashmap 应该拥有所有权

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

我的目标是在 rust book 第 13.1 章的缓存结构上实现建议的改进,即创建一个结构,该结构接受一个函数并使用内存来减少给定函数的调用次数。为此,我创建了一个带有 HashMap 的结构

struct Cacher<T, U, V>
where T: Fn(&U) -> V, U: Eq + Hash
{
calculation: T,
map: HashMap<U,V>,
}

和两种方法,一种是构造函数,另一种是负责内存的。
impl<T, U, V> Cacher<T, U, V>
where T: Fn(&U) -> V, U: Eq + Hash
{
fn new(calculation: T) -> Cacher<T,U,V> {
Cacher {
calculation,
map: HashMap::new(),
}
}

fn value(&mut self, arg: U) -> &V {
match self.map.entry(arg){
Entry::Occupied(occEntry) => occEntry.get(),
Entry::Vacant(vacEntry) => {
let argRef = vacEntry.key();
let result = (self.calculation)(argRef);
vacEntry.insert(result)
}
}
}
}

我使用了 Entry 枚举,因为我没有找到更好的方法来确定 HashMap 是否包含键,如果不包含键,则计算值并将其插入 HashMap 并返回对它的引用。

如果我想编译上面的代码,我会得到一个错误,它说 occEntry 被它的 .get() 方法借用(这对我来说很好)和 .get() "返回引用当前函数拥有的数据的值" .

我的理解是编译器认为 occEntry.get() 所引用的值归函数 value(...) 所有。但是我不应该得到 HashMap 拥有的类型 V 的值的引用吗?编译器是否会因为该值归函数所有并在短时间内保存为结果而感到困惑?
let result = (self.calculation)(argRef);
vacEntry.insert(result)

请注意,由于 insert 方法会消耗 key ,并且此类 argRef 不再有效,因此需要临时保存结果。我也承认 value 的签名可能有问题(参见 Mutable borrow from HashMap and lifetime elision ),但我试图避免 Copy Trait Bound。

为了快速重现问题,我附加了必要的使用语句。谢谢你的帮助。
use std::collections::HashMap;
use std::cmp::Eq;
use std::hash::Hash;
use std::collections::hash_map::{OccupiedEntry, VacantEntry, Entry};

最佳答案

一起来看看 OccupiedEntry::get() 的签名:

 pub fn get(&self) -> &V

这个签名告诉我们的是从 OccupiedEntry 获得的引用。只能活到 OccupiedEntry本身。但是, OccupiedEntry是一个局部变量,因此当函数返回时它会被删除。

我们想要的是一个生命周期绑定(bind)到 HashMap 的引用。的一生。两个 Entry OccupiedEntry 有一个生命周期参数( 'a ),它链接到 &mut self HashMap::entry 中的参数.我们需要一个关于 OccupiedEntry 的方法返回 &'a V .没有这样的方法,但是有一个返回 '&a mut V 的方法。 : into_mut .可变引用可以隐式强制为共享引用,所以我们需要做的就是让你的方法编译通过替换 get()into_mut() .
fn value(&mut self, arg: U) -> &V {
match self.map.entry(arg) {
Entry::Occupied(occ_entry) => occ_entry.into_mut(),
Entry::Vacant(vac_entry) => {
let arg_ref = vac_entry.key();
let result = (self.calculation)(arg_ref);
vac_entry.insert(result)
}
}
}

关于rust - Entry::Occupied.get() 返回一个引用当前函数拥有的数据的值,即使 hashmap 应该拥有所有权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60129097/

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