Rust에는 맵 리터럴 구문이 없습니다. 나는 모르는 정확한 이유를,하지만 난 기대 (예 : 모두 같은 행위 maplike하는 여러 데이터 구조가 있다는 사실 그 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/… .