【问题标题】:Default mutable value from HashMap来自 HashMap 的默认可变值
【发布时间】:2015-06-30 14:40:18
【问题描述】:

假设我有一个HashMap 并且我想获得一个对条目的可变引用,或者如果该条目不存在我想要一个对新对象的可变引用,我该怎么做?我试过使用unwrap_or(),类似这样:

fn foo() {
    let mut map: HashMap<&str, Vec<&str>> = HashMap::new();

    let mut ref = map.get_mut("whatever").unwrap_or( &mut Vec::<&str>::new() );

    // Modify ref.
}

但这不起作用,因为Vec 的生命周期不够长。有没有办法告诉 Rust 我希望返回的 Vecfoo() 具有相同的生命周期?我的意思是有这个明显的解决方案,但我觉得应该有更好的方法:

fn foo() {
    let mut map: HashMap<&str, Vec<&str>> = HashMap::new();

    let mut dummy: Vec<&str> = Vec::new();
    let mut ref = map.get_mut("whatever").unwrap_or( &dummy );

    // Modify ref.
}

【问题讨论】:

  • 您想在任何时候不将dummy 插入地图的情况下执行此操作吗?只是想知道。
  • 没错,尽管这只是我特定用例中的偏好。虽然我可以想象您不想插入 dummy 的情况。

标签: rust lifetime


【解决方案1】:

正如 Shepmaster 所提到的,这里有一个使用入口模式的示例。一开始看起来很冗长,但这避免了分配一个你可能不会使用的数组,除非你需要它。我相信你可以围绕这个创建一个通用函数来减少喋喋不休:)

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

fn foo() {
    let mut map = HashMap::<&str, Vec<&str>>::new();
    let mut result = match map.entry("whatever") {
       Vacant(entry) => entry.insert(Vec::new()),
       Occupied(entry) => entry.into_mut(),
    };

    // Do the work
    result.push("One thing");
    result.push("Then another");
}

这也可以缩短为or_insert,正如我刚刚发现的那样!

use std::collections::HashMap;

fn foo() {
    let mut map = HashMap::<&str, Vec<&str>>::new();
    let mut result = map.entry("whatever").or_insert(Vec::new());

    // Do the work
    result.push("One thing");
    result.push("Then another");
}

【讨论】:

【解决方案2】:

如果您想将您的dummy 添加到地图中,那么这是How to properly use HashMap::entry?Want to add to HashMap using pattern match, get borrow mutable more than once at a time 的副本(或有关entry API 的任何问题)。

如果您不想添加它,那么您的代码就可以了,您只需按照编译器错误消息进行修复即可。您正在尝试使用关键字作为标识符 (ref),并且您需要获得对 dummy (&amp; mut dummy) 的可变引用

use std::collections::HashMap;

fn foo() {
    let mut map: HashMap<&str, Vec<&str>> = HashMap::new();

    let mut dummy: Vec<&str> = Vec::new();
    let f = map.get_mut("whatever").unwrap_or( &mut dummy );
}

fn main() {}

【讨论】:

    猜你喜欢
    • 2014-12-23
    • 2019-02-05
    • 1970-01-01
    • 2021-05-22
    • 1970-01-01
    • 2016-10-24
    • 2014-11-09
    • 1970-01-01
    相关资源
    最近更新 更多