返回Rust HashMap中的确切值

时间:2017-04-14 17:20:35

标签: get hashmap rust key

我找不到合适的方法来返回Rust中get中密钥的确切值。所有现有的{{1}}方法都以不同的格式返回,而不是确切的格式。

2 个答案:

答案 0 :(得分:1)

您可能想要HashMap::remove method-它从映射中删除键并返回原始值,而不是引用:

use std::collections::HashMap;

struct Thing {
    content: String,
}

fn main() {
    let mut hm: HashMap<u32, Thing> = HashMap::new();
    hm.insert(
        123,
        Thing {
            content: "abc".into(),
        },
    );
    hm.insert(
        432,
        Thing {
            content: "def".into(),
        },
    );

    // Remove object from map, and take ownership of it
    let value = hm.remove(&432);

    if let Some(v) = value {
        println!("Took ownership of Thing with content {:?}", v.content);
    };
}

get方法必须返回对该对象的引用,因为原始对象只能存在于一个位置(该对象归HashMap所有)。 remove方法只能将原始对象从其原始所有者中删除,因此可以返回原始对象(即“获得所有权”)。

根据具体情况,另一种解决方案可能是获取引用,对其调用.clone()以创建该对象的新副本(在这种情况下,由于Clone无效)并未为我们的Thing示例对象实现-但如果使用值方式(例如String),则可以使用

最后值得一提的是,在许多情况下您仍然可以使用对对象的引用-例如,上一个示例可以通过获取引用来完成:

use std::collections::HashMap;

struct Thing {
    content: String,
}

fn main() {
    let mut hm: HashMap<u32, Thing> = HashMap::new();
    hm.insert(
        123,
        Thing {
            content: "abc".into(),
        },
    );
    hm.insert(
        432,
        Thing {
            content: "def".into(),
        },
    );

    let value = hm.get(&432); // Get reference to the Thing containing "def" instead of removing it from the map and taking ownership

    // Print the `content` as in previous example.
    if let Some(v) = value {
        println!("Showing content of referenced Thing: {:?}", v.content);
    }
}

答案 1 :(得分:0)

获取给定密钥的值有两种基本方法:get()get_mut()。如果您只想读取值,请使用第一个;如果需要修改值,请使用第二个:

fn get(&self, k: &Q) -> Option<&V>
fn get_mut(&mut self, k: &Q) -> Option<&mut V>

从签名中可以看出,这两种方法都返回Option而不是直接值。原因是可能没有与给定密钥相关的值:

use std::collections::HashMap;

let mut map = HashMap::new();
map.insert(1, "a");
assert_eq!(map.get(&1), Some(&"a")); // key exists
assert_eq!(map.get(&2), None);       // key does not exist

如果您确定地图包含给定的密钥,则可以使用unwrap()从该选项中获取值:

assert_eq!(map.get(&1).unwrap(), &"a");

但是,一般情况下,考虑密钥可能不存在的情况也更好(也更安全)。例如,您可以使用pattern matching

if let Some(value) = map.get(&1) {
    assert_eq!(value, &"a");
} else {
    // There is no value associated to the given key.
}