У Rust немає синтаксису буквального відображення на карті. Я не знаю точної причини, але я сподіваюся, що той факт, що існує безліч структур даних, які діють як карта (наприклад, обидва BTreeMapта HashMap), ускладнить вибір такої.
Тим не менш, ви можете створити макрос, який виконуватиме роботу за вас, як показано в Чому цей макрос HashMap іржі більше не працює? . Ось цей макрос дещо спрощений і має достатню структуру, щоб зробити його доступним на ігровому майданчику :
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));
}
Цей макрос уникає виділення непотрібного проміжного продукту Vec, але він не використовує, HashMap::with_capacityтому можуть бути деякі марні перерозподіли HashMapзначень як додані значення. Можлива більш складна версія макросу, яка підраховує значення, але переваги продуктивності, мабуть, не те, що виграє більшість видів використання макроса.
У нічній версії Rust ви можете уникнути як непотрібного розподілу (і перерозподілу!), Так і необхідності в макросі:
#![feature(array_value_iter)]
use std::array::IntoIter;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::iter::FromIterator;
fn main() {
let s = Vec::from_iter(IntoIter::new([1, 2, 3]));
println!("{:?}", s);
let s = BTreeSet::from_iter(IntoIter::new([1, 2, 3]));
println!("{:?}", s);
let s = HashSet::<_>::from_iter(IntoIter::new([1, 2, 3]));
println!("{:?}", s);
let s = BTreeMap::from_iter(IntoIter::new([(1, 2), (3, 4)]));
println!("{:?}", s);
let s = HashMap::<_, _>::from_iter(IntoIter::new([(1, 2), (3, 4)]));
println!("{:?}", s);
}
Потім цю логіку можна також обернути назад у макрос:
#![feature(array_value_iter)]
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
macro_rules! collection {
($($k:expr => $v:expr),* $(,)?) => {
std::iter::Iterator::collect(std::array::IntoIter::new([$(($k, $v),)*]))
};
($($v:expr),* $(,)?) => {
std::iter::Iterator::collect(std::array::IntoIter::new([$($v,)*]))
};
}
fn main() {
let s: Vec<_> = collection![1, 2, 3];
println!("{:?}", s);
let s: BTreeSet<_> = collection! { 1, 2, 3 };
println!("{:?}", s);
let s: HashSet<_> = collection! { 1, 2, 3 };
println!("{:?}", s);
let s: BTreeMap<_, _> = collection! { 1 => 2, 3 => 4 };
println!("{:?}", s);
let s: HashMap<_, _> = collection! { 1 => 2, 3 => 4 };
println!("{:?}", s);
}
Дивитися також:
grabbag_macrosящику також є одна . Ви можете побачити джерело тут: github.com/DanielKeep/rust-grabbag/blob/master/grabbag_macros/… .