У 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/… .