gpt4 book ai didi

rust - 如何将 Entry API 与仅在 Entry 为空时才构建的昂贵 key 一起使用?

转载 作者:行者123 更新时间:2023-11-29 08:20:18 27 4
gpt4 key购买 nike

是否可以使用 Entry 通过 AsRef<str> 获取值的 API , 但用 Into<String> 插入它?

这是工作示例:

use std::collections::hash_map::{Entry, HashMap};

struct Foo;

#[derive(Default)]
struct Map {
map: HashMap<String, Foo>,
}

impl Map {
fn get(&self, key: impl AsRef<str>) -> &Foo {
self.map.get(key.as_ref()).unwrap()
}

fn create(&mut self, key: impl Into<String>) -> &mut Foo {
match self.map.entry(key.into()) {
Entry::Vacant(entry) => entry.insert(Foo {}),
_ => panic!(),
}
}

fn get_or_create(&mut self, key: impl Into<String>) -> &mut Foo {
match self.map.entry(key.into()) {
Entry::Vacant(entry) => entry.insert(Foo {}),
Entry::Occupied(entry) => entry.into_mut(),
}
}
}

fn main() {
let mut map = Map::default();
map.get_or_create("bar");
map.get_or_create("bar");
assert_eq!(map.map.len(), 1);
}

playground

我的问题是在get_or_create一个String将始终被创建,导致不需要的内存分配,即使它不需要被占用的条目。有可能以任何方式解决这个问题吗?也许以一种巧妙的方式使用 Cow

最佳答案

安全地,你不能。这是目前入口API的局限性,没有很好的解决办法。预期的解决方案是“原始”入口 API。参见 Stargateur's answer for an example of using it .

使用 Entry API 的唯一稳定解决方案是始终克隆 key :

map.entry(key.clone()).or_insert(some_value);

在 Entry API 之外,您可以检查 map 是否包含值,如果不包含则插入:

if !map.contains_key(&key) {
map.insert(key.clone(), some_value);
}

map.get(&key).expect("This is impossible as we just inserted a value");

另见:

对于非基于entry的解决方案,请参见:

关于rust - 如何将 Entry API 与仅在 Entry 为空时才构建的昂贵 key 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54080605/

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