Rust 2025中的HashMap:字面量、宏和最佳实践

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

在Rust中创建HashMap:从痛苦到优雅的2025年

\n\n

如果你曾经用Rust编程并问过自己 "How do I create a HashMap literal?" —— 你并不孤单。这个问题在Stack Overflow上获得了数千次浏览,这并非没有原因。在Python或JavaScript等语言中,创建字典不过是一对花括号的事。而在Rust中,情况要稍微复杂一些……但这只是第一印象。

\n\n

到了2025年,Rust生态系统已经取得了长足的进步。新的宏出现了,常量的处理得到了改进,编译器也变得更加智能。在本文中,我们将探讨 所有创建HashMap的方法,从经典方法到最新方法。你将学习如何编写不仅可用,而且美观、高效的代码。

\n\n

我们开始吧!🦀

\n\n

为什么Rust没有内置的HashMap字面量?

\n\n

这可能是初学者最常问的问题。答案很简单:Rust不是Python。Rust在语法层面没有为集合提供“魔法”,因为该语言追求可预测性和对内存的控制。

\n\n

想象一下,你写下:

\n\n
let map = {"key1": "value1", "key2": "value2"};
\n\n

看起来合理吗?是的。但是,如果键或值不是字符串,而是一些复杂的结构呢?编译器如何知道使用哪个分配器?哈希处理又该如何进行?Rust将这些决定留给了开发者。

\n\n

正因如此,在标准库中创建HashMap使用的是 HashMap::new() 和 .insert() 方法。但是,为了创建一个只有三对键值对的字典而编写10行代码,这确实令人痛苦。幸运的是,有解决方案。

\n\n

方法 #1:经典方法 —— HashMap::new() + insert()

\n\n

我们从基础开始。这是最清晰、最透明的方法。你创建一个空的HashMap,然后填充它:

\n\n
use std::collections::HashMap;\n\nfn main() {\n    let mut scores = HashMap::new();\n    scores.insert("Alice".to_string(), 42);\n    scores.insert("Bob".to_string(), 27);\n    scores.insert("Charlie".to_string(), 35);\n\n    println!("{:?}", scores);\n}
\n\n

优点:

\n
    \n
  • 完全控制整个过程。
  • \n
  • 可以根据条件添加元素。
  • \n
  • 不需要额外的依赖。
  • \n
\n\n

缺点:

\n
    \n
  • 过于冗长。
  • \n
  • 需要 mut。
  • \n
  • 不适用于常量。
  • \n
\n\n

这种方法适用于动态填充,但对于静态数据来说,它过于繁琐。

\n\n

方法 #2:from() —— 当数据已就绪时

\n\n

如果你有一个元组向量,可以使用 HashMap::from():

\n\n
use std::collections::HashMap;\n\nfn main() {\n    let data = vec![\n        ("Alice", 42),\n        ("Bob", 27),\n        ("Charlie", 35),\n    ];\n\n    let scores: HashMap<&str, i32> = HashMap::from(data);\n    println!("{:?}", scores);\n}
\n\n

这已经更接近“字面量”了。看起来更简洁,但仍然需要一个中间向量。运行速度很快,但对于大型数据集,由于双重内存分配,可能效率不高。

\n\n

方法 #3:collect() —— 函数式方法

\n\n

迭代器的爱好者会喜欢这种方法:

\n\n
use std::collections::HashMap;\n\nfn main() {\n    let scores: HashMap<&str, i32> = [\n        ("Alice", 42),\n        ("Bob", 27),\n        ("Charlie", 35),\n    ].iter().cloned().collect();\n\n    println!("{:?}", scores);\n}
\n\n

漂亮吗?是的。可读吗?勉强可以。但这是Rust中最惯用的方法之一。.iter().cloned().collect() 是将数组转换为集合的标准模式。

\n\n

顺便说一句,如果你的键和值实现了 Copy,可以使用 .copied() 代替 .cloned() —— 这样会稍微快一些。

\n\n

方法 #4:hashmap! 宏 —— 来自2025年的救星

\n\n

接下来

博客

书籍推荐