首页 > 解决方案 > `HashMap::get_mut` 导致“返回对本地值的引用”,任何有效的解决方法?

问题描述

围绕这个问题有很多问题,解决方案主要是“使用Entry”。

然而,这是一个问题,因为HashMap::entry()需要一个拥有的值,这意味着即使密钥已经存在并且我们只想就地更新值,也可能意味着昂贵的副本/分配,因此使用get_mut. 然而,get_mut对本地引用的使用导致 rustc 假设所述引用被存储到哈希映射中,因此返回哈希映射是一个错误

use std::borrow::Cow;
use std::collections::HashMap;

fn get_string() -> String { String::from("xxxxxxx") }
fn foo() -> HashMap<Cow<'static, str>, usize> {
    let mut v = HashMap::new();

    // stand-in for "get a string slice as key",
    // real case is getting a String from an 
    // mpsc and the key being a segment of that string
    let s = get_string();
    // stand-in for a structure which contains an `Option<Cow>`
    let k = Cow::from(&s[2..3]);

    // because of get_mut, `&s` is apparently considered to be stored in `v`?
    if let Some(e) = v.get_mut(&k) {
        *e += 1;
    } else {
        v.insert(Cow::from(k.into_owned()), 0);
    }

    v
}

请注意,第 9~13 行的操作是为了阐明模式的要点,但get_mut仅此一项就足以触发问题

有没有不影响效率的方法,还是急切分配是唯一的方法?(注意:因为这是一个静态问题,动态门喜欢contains_keyget显然不做任何事情)。

标签: rusthashmap

解决方案


根据文档HashSet::get_mut()需要一个类型的值,&Q以便散列的键实现Borrow<Q>

您的哈希的关键是Cow<'static, str>实现 Borrow<str>. 这意味着您可以使用 a&Cow<'static, str>或 a &str。但你正在度过&Cow<'local, str>一段'local一生。编译器尝试将其'local'static生命周期相匹配并发出一些令人困惑的错误消息。

解决方案实际上很简单,因为您可以&strCowcallk.as_ref()或 doing中获得 an &*k,并且 the 的生命周期&str不受限制:(playground

let k = Cow::from(&s[2..3]);
if let Some(e) = v.get_mut(k.as_ref()) { /* ...*/ }

推荐阅读