为何在HashMap<char, i32>中需用&char而非char索引键?
问题:Rust里HashMap<char, i32>为啥不能用
letters['a']直接取值? 我确认letters是std::collections::hash::map::HashMap<char, i32>类型,'a'是char类型,&'a'是&char类型,但为啥只有letters[&'a']能正常打印值,用letters['a']就不行?代码如下:
use std::collections::HashMap; fn main() { let mut letters = HashMap::new(); for ch in "a short treatise on fungi".chars() { letters.entry(ch).and_modify(|counter| *counter += 1).or_insert(1); } println!("{}", letters[&'a']); }
解答
核心原因是Rust的HashMap索引运算符[]要求传入键的引用,而不是键本身的所有权。具体细节:
HashMap<K, V>实现的Indextrait定义是impl<K, Q, V> Index<&Q> for HashMap<K, V>,这里要求K可以借用为Q(即K: Borrow<Q>),同时Q需要支持相等判断和哈希计算。- 对于
char类型,它本身实现了Borrow<char>,所以&char完全符合索引参数的要求。
直接写letters['a']时,传递的是char的所有权,而索引运算符期待的是引用类型,这就会触发类型不匹配的编译错误。
常用的解决方式有两种:
- 像示例代码那样传递键的引用:
letters[&'a'] - 使用
get方法,它同样接受引用,返回Option<&V>,比如letters.get(&'a').unwrap()(注意:如果键不存在,unwrap会触发panic,实际项目建议用match或if let处理空值情况)
如果需要修改对应的值,可以用get_mut(&'a'),同样需要传递键的引用。
内容的提问来源于stack exchange,提问作者Eason
相关产品推荐
相关产品推荐

