如何向hashmap值的向量追加?

use std::collections::HashMap;

fn main() {
    let mut dict = HashMap::new();
    let mut prefix = ["", ""];

    let lorem = "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eum debitis earum quidem dolorem quos consequatur perspiciatis architecto! Reiciendis rem est blanditiis fugiat quidem similique suscipit soluta, ab veniam, laborum numquam. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eum debitis earum quidem dolorem quos consequatur perspiciatis architecto! Reiciendis rem est blanditiis fugiat quidem similique suscipit soluta, ab veniam, laborum numquam.";

    for token in lorem.split_whitespace() {
        if prefix[0] != "" {

            let key = prefix.join(" ");

            if !dict.contains_key(&key) {
                dict.insert(key, vec![token]);
            } else {
                let v = dict.get(&key);
                v.push(token); // does not actually return a vector
            }
        }

        prefix[0] = prefix[1];
        prefix[1] = token;
    }
}

问题是行let v = dict.get(&key);通常我希望能够推到向量上,但它似乎返回某种集合,我不确定如何附加到它.

推荐答案

惯用解决方案

解决问题的惯用方法是使用entry,如下所示:

for token in lorem.split_whitespace() {
    if prefix[0] != "" {

        let key = prefix.join(" ");

        match dict.entry(key) {
            Entry::Vacant(e) => { e.insert(vec![token]); },
            Entry::Occupied(mut e) => { e.get_mut().push(token); }
        }
    }

    prefix[0] = prefix[1];
    prefix[1] = token;
}

如果密钥不存在,您将得到一个空条目,可以用来插入新值.如果它确实存在,您将获得一个被占用的条目,可以使用它修改当前值.如果你想知道更多,看看documentation.

休恩在 comments 中提出的替代方案

这一个甚至更短,而且在我看来,一旦你理解了发生的事情:

for token in lorem.split_whitespace() {
    if prefix[0] != "" {
        let key = prefix.join(" ");
        dict.entry(key).or_insert(Vec::new()).push(token);
    }

    prefix[0] = prefix[1];
    prefix[1] = token;
}

为什么你的代码不起作用

get返回Option<&Vec<&str>>.您需要将Vec从选项中删除,但即使在这种情况下,您也不能对其进行变异,因为它是一个共享引用.您可以将get_mutunwrap组合使用,如下所示(但是,这被认为是糟糕的样式.您应该真正使用entry):

for token in lorem.split_whitespace() {
    if prefix[0] != "" {

        let key = prefix.join(" ");

        if !dict.contains_key(&key) {
            dict.insert(key, vec![token]);
        } else {
            let v = dict.get_mut(&key).unwrap();
            v.push(token);
        }
    }

    prefix[0] = prefix[1];
    prefix[1] = token;
}

Rust相关问答推荐

为什么在Rust struct 中只允许最后一个字段具有动态大小的类型

如何最好地并行化修改同一Rust向量的多个切片的代码?

如何从铁 rust 中呼唤_mm_256_mul_ph?

在Rust中赋值变量有运行时开销吗?

为什么实例方法可以像Rust中的静态方法一样被调用?

定义采用更高级类型泛型的性状

如何为rust trait边界指定多种可能性

无法实现整型类型的泛型FN

将Vec<;U8&>转换为Vec<;{Float}&>

为什么 GAT、生命周期和异步的这种组合需要 `T: 'static`?

使用 select 处理 SIGINT 和子等待!无阻塞

在 Rust 中,在第一个空格上分割字符串一次

可以在旋转循环中调用try_recv()吗?

如何获取模块树?

没有明确地说return会产生错误:match arms have incompatible types

如何在 Rust 中将枚举变体转换为 u8?

&self 参数在 trait 的功能中是必需的吗?

如何判断服务器是否正确接收数据

BigUint 二进制补码

在同一向量 Rust 中用另一个字符串扩展一个字符串