如何在Rust中创建HashMap文字?在Python中,我可以这样做:
hashmap = {
'element0': {
'name': 'My New Element',
'childs': {
'child0': {
'name': 'Child For Element 0',
'childs': {
...
}
}
}
},
...
}
Run Code Online (Sandbox Code Playgroud)
在Go中这样:
type Node struct {
name string
childs map[string]Node
}
hashmap := map[string]Node {
"element0": Node{
"My New Element",
map[string]Node {
'child0': Node{
"Child For Element 0",
map[string]Node {}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
She*_*ter 59
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));
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*ger 30
从 Rust 1.56 开始,您可以使用 初始化 HashMap from()
,这有点像拥有 HashMap 文字。 from()
接受一个键值对数组。你可以这样使用它:
use std::collections::HashMap;
fn main() {
let hashmap = HashMap::from([
("foo", 1),
("bar", 2)
]);
}
Run Code Online (Sandbox Code Playgroud)
Dav*_* J. 26
我推荐maplit箱子.
引用文档:
具有特定类型的容器文字的宏.
#[macro_use] extern crate maplit;
let map = hashmap!{
"a" => 1,
"b" => 2,
};
Run Code Online (Sandbox Code Playgroud)
maplit crate对映射宏使用=>语法.由于语法上常规macro_rules的限制,不可能使用:as separator作为分隔符!宏.
请注意,生锈宏很灵活,您可以使用哪些括号进行调用.您可以将它们用作hashmap!{}或hashmap![]或hashmap!().这个箱子建议{}作为map&set宏的约定,它匹配它们的Debug输出.
宏
btreemap从键值对列表中创建BTreeMap
btreeset从元素列表中创建BTreeSet.
hashmap从键值对列表中创建HashMap
hashset从元素列表中创建HashSet.
jup*_*p0r 24
有一个如何在文档中HashMap
实现此目的的示例:
let timber_resources: HashMap<&str, i32> =
[("Norway", 100),
("Denmark", 50),
("Iceland", 10)]
.iter().cloned().collect();
Run Code Online (Sandbox Code Playgroud)
正如@Johannes 在评论中指出的那样,可以使用,vec![]
因为:
Vec<T>
实现IntoIterator<T>
特征HashMap<K, V>
工具 FromIterator<Item = (K, V)>
这意味着你可以这样做:
let map: HashMap<String, String> = vec![("key".to_string(), "value".to_string())]
.into_iter()
.collect();
Run Code Online (Sandbox Code Playgroud)
您可以使用,&str
但如果不是,则可能需要注释生命周期'static
:
let map: HashMap<&str, usize> = vec![("one", 1), ("two", 2)].into_iter().collect();
Run Code Online (Sandbox Code Playgroud)
您可以使用velcro
箱子*。它类似于maplit
其他答案中推荐的,但具有更多的集合类型、更好的语法(至少在我看来!)和更多功能。
假设您想使用String
s 而不是&str
,您的确切示例将如下所示:
use std::collections::HashMap;
use velcro::hash_map;
struct Node {
name: String
children: HashMap<String, Node>,
}
let map = hash_map! {
String::from("element0"): Node {
name: "My New Element".into(),
children: hash_map! {
String::from("child0"): Node {
name: "child0".into(),
children: hash_map!{}
}
}
}
};
Run Code Online (Sandbox Code Playgroud)
String
由于s 的构造方式,这有点难看。但它可以变得更简洁,无需更改密钥类型,通过使用hash_map_from!
它会自动进行转换:
use std::collections::HashMap;
use velcro::{hash_map, hash_map_from};
let map: HashMap<String, Node> = hash_map_from! {
"element0": Node {
name: "My New Element".into(),
children: hash_map_from! {
"child0": Node {
name: "child0".into(),
children: hash_map!{}
}
}
}
};
Run Code Online (Sandbox Code Playgroud)
这并不比 Go 版本更冗长。
*全面披露:我是这个箱子的作者。