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