web-dev-qa-db-fra.com

Comment créer un littéral HashMap?

Comment créer un littéral HashMap dans Rust? En Python je peux le faire ainsi:

hashmap = {
   'element0': {
       'name': 'My New Element',
       'childs': {
           'child0': {
               'name': 'Child For Element 0',
               'childs': {
                   ...
               }
           }
       }
   },
   ...
}

Et dans Go comme ça:

type Node struct {
    name string
    childs map[string]Node
}

hashmap := map[string]Node {
    "element0": Node{
        "My New Element",
        map[string]Node {
            'child0': Node{
                "Child For Element 0",
                map[string]Node {}
            }
        }
    }
}
50
Maxim Samburskiy

Il n'y a pas de syntaxe littérale de carte dans Rust. Je ne connais pas la raison exacte , mais je m'attends à ce que le fait qu'il existe plusieurs structures de données qui agissent comme des mapliks (tels que les deux BTreeMap et HashMap ), il serait difficile d'en choisir un.

Cependant, vous pouvez créer une macro pour faire le travail pour vous, comme démontré dans Pourquoi cette macro Rust HashMap macro ne fonctionne plus? . Voici cette macro simplifiée un peu et avec suffisamment de structure pour le rendre exécutable dans la cour de récréation :

macro_rules! map(
    { $($key:expr => $value:expr),+ } => {
        {
            let mut m = ::std::collections::HashMap::new();
            $(
                m.insert($key, $value);
            )+
            m
        }
     };
);

fn main() {
    let names = map!{ 1 => "one", 2 => "two" };
    println!("{} -> {:?}", 1, names.get(&1));
    println!("{} -> {:?}", 10, names.get(&10));
}
56
Shepmaster

Je recommande la caisse maplit .

Pour citer la documentation:

Macros pour les littéraux de conteneur avec un type spécifique.

#[macro_use] extern crate maplit;

let map = hashmap!{
    "a" => 1,
    "b" => 2,
};

La caisse maplit utilise la syntaxe => pour les macros de mappage. Il n'est pas possible d'utiliser: comme séparateur en raison de la syntaxe des restrictions dans les macro_rules régulières! macros.

Notez que Rust sont flexibles entre les crochets que vous utilisez pour l'invocation. Vous pouvez les utiliser comme hashmap! {} Ou hashmap! [] Ou hashmap! (). Cette caisse suggère {} comme la convention pour les macros map & set, elle correspond à leur sortie de débogage.

Macros

btreemap Créez un BTreeMap à partir d'une liste de paires clé-valeur

btreeset Créez un BTreeSet à partir d'une liste d'éléments.

hashmap Créer un HashMap à partir d'une liste de paires clé-valeur

hashset Créez un HashSet à partir d'une liste d'éléments.

23
David J.

Il y a un exemple de comment y parvenir dans la documentation pour HashMap :

 let timber_resources: HashMap<&str, i32> =
    [("Norway", 100),
     ("Denmark", 50),
     ("Iceland", 10)]
    .iter().cloned().collect();
17
jupp0r