No hay una sintaxis literal de mapa en Rust. No sé la razón exacta , pero espero que el hecho de que haya múltiples estructuras de datos que actúan como un mapa (como ambos BTreeMap
y HashMap
) dificultaría la elección de una.
Sin embargo, puede crear una macro para que haga el trabajo por usted, como se demuestra en ¿Por qué esta macro HashMap de óxido ya no funciona? . Aquí está esa macro simplificada un poco y con suficiente estructura para que se pueda ejecutar en el patio de recreo :
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));
}
Esta macro evita la asignación de un intermedio innecesario Vec
, pero no se usa, HashMap::with_capacity
por lo que puede haber algunas reasignaciones inútiles de los HashMap
valores a medida que se agregan. Es posible una versión más complicada de la macro que cuenta los valores, pero los beneficios de rendimiento probablemente no sean algo de lo que la mayoría de los usos de la macro se beneficiarían.
En una versión nocturna de Rust, puede evitar tanto la asignación innecesaria (¡y la reasignación!) Como la necesidad de una macro:
#![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);
}
Esta lógica también se puede volver a envolver en una macro:
#![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);
}
Ver también:
grabbag_macros
caja. Puede ver la fuente aquí: github.com/DanielKeep/rust-grabbag/blob/master/grabbag_macros/… .