我找不到一种合适的方法在 Rust 的 HashMap
中精确返回键的值。所有现有的get
方法返回的格式与精确格式不同。
你可能想要使用HashMap::remove
方法 - 它会从映射中删除该键并返回原始值而不是引用:
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()
以创建对象的副本(在这种情况下,它不起作用,因为我们的 Thing
示例对象未实现 Clone
- 但如果值是例如 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);
}
}
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");
然而,一般来说,考虑到键可能不存在的情况会更好(也更安全)。例如,您可以使用模式匹配:
if let Some(value) = map.get(&1) {
assert_eq!(value, &"a");
} else {
// There is no value associated to the given key.
}
HashMap<T>.get(k)
返回一个Option<&T>
。如果问题的作者想要问为什么值被包装在Option中,那么现有的答案似乎很好地回答了这个问题。如果发帖人想要问为什么返回值的是对该值的引用,则需要另一个答案。但是,如果问题没有更多的明确性,我们无法确定正在被问到的是哪些事情。 - jbg