如何在Rust中创建一个HashMap常量?在Python中我可以这样做:
hashmap = {
'element0': {
'name': 'My New Element',
'childs': {
'child0': {
'name': 'Child For Element 0',
'childs': {
...
}
}
}
},
...
}
在围棋里是这样的:
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 {}
}
}
}
}
9条答案
按热度按时间uemypmqf1#
Rust中没有map文字语法,我不知道 * 确切 * 的原因,但我认为有多个数据结构表现得像map(比如
BTreeMap
和HashMap
),这会使选择一个变得困难。生 rust 1.56
现在,许多集合都提供了使用
From
或Into
从数组参数进行转换的功能:可以将此逻辑 Package 回宏中,以获得一些语法糖:
生 rust 1.51
从Rust 1.51开始,你可以使用按值数组迭代器和
FromIterator
来收集到很多种集合中:请注意,在Rust 1.53中,并不总是需要
std::array::IntoIter
。可以将此逻辑 Package 回宏中,以获得一些语法糖:
这些解决方案避免了不必要的分配和重新分配。
另见:
先前版本
您可以创建一个宏来完成这项工作,如Why does this rust HashMap macro no longer work?中所示。下面是稍微简化的宏,它具有足够的结构,使其成为runnable in the playground:
这个宏避免了分配一个不需要的中间
Vec
,但是它没有使用HashMap::with_capacity
,所以在增加值的时候可能会有一些无用的HashMap
的重新分配。一个更复杂的计算值的宏版本是可能的,但是性能上的好处可能不是大多数宏使用者所能受益的。nfzehxib2#
我推荐maplit板条箱。
引用文件:
特定类型容器文本的宏。
maplit crate使用
=>
语法进行Map宏。由于常规macro_rules!
宏中的语法限制,无法使用:
作为分隔符。注意,rust宏可以灵活地使用方括号进行调用。您可以使用
hashmap!{}
或hashmap![]
或hashmap!()
。此crate建议将{}
作为map & set宏的约定,它与它们的调试输出相匹配。宏
btreemap
从键值对列表中创建BTreeMap
btreeset
从元素列表中创建一个BTreeSet
。hashmap
从键值对列表中创建HashMap
hashset
从元素列表中创建一个HashSet
。nafvub8i3#
在documentation for
HashMap
中有一个如何实现这一点的示例:14ifxucb4#
从Rust 1.56开始,你可以使用
from()
初始化一个HashMap,这有点像HashMap文字。from()
接受一个键值对数组。你可以这样使用它:yb3bgrhw5#
正如@Johannes在评论中指出的,使用
vec![]
是可能的,因为:Vec<T>
实现了IntoIterator<T>
特征HashMap<K, V>
实现了FromIterator<Item = (K, V)>
这意味着你可以这样做:
您可以使用
&str
,但如果它不是'static
,则可能需要注解生存期:e3bfsja26#
从Rust 1.51开始,
IntoIterator
是为数组实现的,因此您可以使用from_iter
方法创建一个HashMap
,而无需克隆:从Rust 1.56开始(目前是每晚),您可以使用
From<[(K, V); N]>
实现,它甚至更简洁:lx0bsm1f7#
您可以使用
velcro
crate*,它类似于其他答案中推荐的maplit
,但具有更多的集合类型、更好的语法(至少在我看来!)和更多的特性。假设您希望使用
String
s而不是&str
,则确切的示例如下所示:由于
String
的构造方式,这有点难看,但是可以通过使用hash_map_from!
自动进行转换来使它变得更简洁,而不改变密钥类型:这并不比Go语言的版本冗长多少。
**全面披露:我是这个箱子的作者。
pwuypxnk8#
对于一个元素
如果您希望在一行中只使用一个元素初始化map(并且代码中没有可见的变化),您可以执行以下操作:
这要归功于
Option
能够使用into_iter()
变成Iterator
的实用性。在真实的代码中,您可能不需要帮助编译器处理以下类型:
还有一种方法可以将其链接起来,让多个元素执行类似于
Some(a).into_iter().chain(Some(b).into_iter()).collect()
的操作,但这会更长,可读性更差,而且可能存在一些优化问题,因此我建议不要使用它。vdzxcuhz9#
我看过很多花哨的解决方案,但我想要一些简单的。为此,这里有一个特点:
我认为这是一个很好的选择,因为Ruby和Nim基本上已经使用了它。