【问题标题】:Return exact value in Rust HashMap在 Rust HashMap 中返回精确值
【发布时间】:2017-09-10 23:43:27
【问题描述】:

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

【问题讨论】:

  • 欢迎来到 StackOverflow!不幸的是,你的问题并不像它可能的那样清楚。你能澄清一下吗? “精确格式”是什么意思?你的意思是确切的类型?如果你提供一个你认为应该可以工作但没有用的 sn-p 代码会有所帮助:)
  • 不确定问题是否已被编辑,但它对我来说非常有意义
  • 问题是“格式”这个词使问题变得模糊不清。 HashMap<T>.get(k) 返回一个 Option<&T>。如果问题作者打算问为什么值被包裹在一个选项中,那么现有的答案似乎很好地回答了这个问题。如果发帖者打算询问为什么返回对值的引用,则另一个答案将是合适的。但是,如果问题没有更明确的说明,我们就无法确定这些问题中的哪一个被问到了。

标签: get hashmap rust key


【解决方案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);
    }
}

【讨论】:

    【解决方案2】:

    有两种获取给定键值的基本方法: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.
    }
    

    【讨论】:

    • 我认为问题在于,返回的东西是一个引用,而不是一个值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-04
    • 2020-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    相关资源
    最近更新 更多