1

假设我有一个&mut std::collections::HashMap,我想把所有的键都变成大写。以下代码可以解决问题:

use std::collections::HashMap;

fn keys_to_upper<T>(map: &mut HashMap<String, T>) {
    let mut tmp = Vec::with_capacity(map.len());
    for (key, val) in map.drain() {
        tmp.push((key.to_ascii_uppercase(), val));
    }
    for (key, val) in tmp {
        map.insert(key, val);
    }
}

不幸的是,我没有 a HashMapbut a &mut serde_json::Map,我想把所有的键都变成大写。没有.drain()方法。我可以.into_iter()改用,但这只会给我对键和值的可变引用。要再次将它们插入地图,我必须克隆它们,这会损害性能。

这里有什么方法可以解决该.drain()方法的缺失吗?

4

1 回答 1

4

Rust 程序员工具箱中的一个不错的工具:std::mem::take. 如果类型实现了默认值,这可以让您将 a 更改&mut T为 a T(如果没有,但该类型仍然有一个您可以使用的虚拟/廉价值,那么std::mem::replace这是您选择的函数)。

应用于您当前的用例,这给出:

use serde_json::{Map, Value};

fn keys_to_upper<T>(map: &mut Map<String, Value>) {
    *map = std::mem::take(map)
        .into_iter()
        .map(|(k, v)| (k.to_ascii_uppercase(), v))
        .collect();
}
于 2020-08-07T20:43:56.573 回答