Функция Rust, которая принимает HashMap и BtreeMap - PullRequest
0 голосов
/ 26 января 2019
fn edit_map_values(
            map1: &mut HashMap<String, i128> || &mut BTreeMap<String, i128>){
    for tuple in map1.iter_mut() {
        if !map1.contains_key(&"key1") {
             *tuple.1 += 1;
        }
    }
    map1.insert(&"key2", 10);
}

Как написать одну функцию, которая принимает HashMap и BtreeMap, как в примере выше?

Ответы [ 2 ]

0 голосов
/ 27 января 2019

Еще до релиза 1.0 существовали черты Map и MutableMap, но они были удалены до стабилизации.Система типов Rust в настоящее время не может выразить эти черты в хорошем смысле из-за отсутствия типов с более высоким родом.

Эклектичный ящик предоставляет экспериментальные признаки сбора, но они не былиобновляется в течение года, поэтому я не уверен, что они по-прежнему полезны для последних версий Rust.

Дополнительная информация:

0 голосов
/ 26 января 2019

Можно абстрагироваться от типов с помощью признаков, и для вашего конкретного случая использования вы можете взглянуть на этот более ограниченный пример .

use core::{borrow::Borrow, hash::Hash};
use std::collections::{BTreeMap, HashMap};

trait GenericMap<K, V> {
    fn contains_key<Q>(&self, k: &Q) -> bool
    where
        K: Borrow<Q>,
        Q: Hash + Eq + Ord;

    fn each_mut<F>(&mut self, cb: F)
    where
        F: FnMut((&K, &mut V));

    fn insert(&mut self, key: K, value: V) -> Option<V>;
}

impl<K, V> GenericMap<K, V> for HashMap<K, V>
where
    K: Eq + Hash,
{
    fn contains_key<Q>(&self, k: &Q) -> bool
    where
        K: Borrow<Q>,
        Q: Hash + Eq + Ord,
    {
        self.contains_key(k)
    }

    fn each_mut<F>(&mut self, mut cb: F)
    where
        F: FnMut((&K, &mut V)),
    {
        self.iter_mut().for_each(|x| cb(x))
    }

    fn insert(&mut self, key: K, value: V) -> Option<V> {
        self.insert(key, value)
    }
}

impl<K, V> GenericMap<K, V> for BTreeMap<K, V>
where
    K: Ord,
{
    fn contains_key<Q>(&self, k: &Q) -> bool
    where
        K: Borrow<Q>,
        Q: Hash + Eq + Ord,
    {
        self.contains_key(k)
    }

    fn each_mut<F>(&mut self, mut cb: F)
    where
        F: FnMut((&K, &mut V)),
    {
        self.iter_mut().for_each(|x| cb(x))
    }

    fn insert(&mut self, key: K, value: V) -> Option<V> {
        self.insert(key, value)
    }
}

fn edit_map_values<T: GenericMap<String, i128>>(map: &mut T) {
    map.each_mut(|(k, v)| {
        if k != "key1" {
            *v += 1;
        }
    });
    map.insert("key2".into(), 10);
}

fn main() {
    let mut hm: HashMap<String, i128> = [("One".into(), 1), ("Two".into(), 2)]
        .iter()
        .cloned()
        .collect();
    let mut btm: BTreeMap<String, i128> = [("Five".into(), 5), ("Six".into(), 6)]
        .iter()
        .cloned()
        .collect();
    dbg!(&hm);
    dbg!(&btm);
    edit_map_values(&mut hm);
    edit_map_values(&mut btm);
    dbg!(&hm);
    dbg!(&btm);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...