Không có cú pháp chữ bản đồ trong Rust. Tôi không biết lý do chính xác , nhưng tôi cho rằng thực tế là có nhiều cấu trúc dữ liệu hoạt động giống như bản đồ (chẳng hạn như cả hai BTreeMap
vàHashMap
) sẽ khiến cho việc chọn một trở nên khó khăn.
Tuy nhiên, bạn có thể tạo một macro để thực hiện công việc cho mình, như được trình bày trong Tại sao macro HashMap rỉ sét này không còn hoạt động nữa? . Đây là macro được đơn giản hóa một chút và có đủ cấu trúc để làm cho nó có thể chạy được trong sân chơi :
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));
}
Macro này tránh phân bổ một trung gian không cần thiết Vec
, nhưng nó không sử dụng HashMap::with_capacity
vì vậy có thể có một số phân bổ lại vô ích HashMap
khi các giá trị được thêm vào. Có thể có một phiên bản phức tạp hơn của macro để đếm các giá trị, nhưng lợi ích về hiệu suất có lẽ không phải là thứ mà hầu hết các trường hợp sử dụng macro sẽ được hưởng lợi.
Trong phiên bản Rust hàng đêm, bạn có thể tránh được cả phân bổ không cần thiết (và phân bổ lại!) Cũng như nhu cầu về 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);
}
Logic này sau đó cũng có thể được gói lại thành một 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);
}
Xem thêm:
grabbag_macros
thùng. Bạn có thể xem nguồn tại đây: github.com/DanielKeep/rust-grabbag/blob/master/grabbag_macros/… .