В Rust нет синтаксиса литерала карты. Я не знаю точной причины, но полагаю, что тот факт, что существует несколько структур данных, которые действуют подобно карте (например, обе BTreeMapи HashMap), затруднит выбор одной.
Однако вы можете создать макрос, который сделает эту работу за вас, как показано в разделе Почему этот макрос rust 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добавляемых значений as. Возможна более сложная версия макроса, которая подсчитывает значения, но преимущества в производительности, вероятно, не то, от чего выиграет большинство применений макроса.
В ночной версии 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/… .