Rust创建HashMap编译报错:需用`::<...>`而非`<...>`指定泛型参数
Rust HashMap泛型初始化编译错误修复
问题说明
- 实现目标:创建
HashMap存储Vec变量data中各元素的最长连续重复长度(即连续相同元素的个数) - 预期效果:输入序列
[1,1,3,1,1]时,最终得到的HashMap结果为{1: 2} - 遇到问题:代码无法通过编译,编译器输出错误如下:
Compiling playground v0.0.1 (/playground) error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,` --> src/main.rs:7:39 | 7 | let mut counts = HashMap::HashMap<u8, u8>::new(); | ^ expected one of 8 possible tokens | help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments | 7 | let mut counts = HashMap::HashMap::<u8, u8>::new();
- 原始实现代码:
use std::collections::HashMap; use std::cmp; fn main() { let data: Vec<u8> = vec![1,1,3,1,1]; let mut counts = HashMap::HashMap<u8, u8>::new(); let mut current_count = 0; for (i, &x) in data.iter().enumerate() { if i > 0 { if x == data[i-1] { current_count += 1; counts.entry(x).or_insert(cmp::max(current_count, *counts.get(&x).unwrap())); } else { current_count = 0; } } } println!("{:?}", counts); }
错误原因
- 路径重复书写:已经通过
use std::collections::HashMap导入了HashMap类型,初始化时写HashMap::HashMap属于重复书写类型名,路径本身就是错误的。 - 泛型语法错误:Rust中在表达式位置(非类型声明位置)指定泛型参数时,必须使用涡轮鱼(turbofish)语法
::<>,不能直接在类型名后接<>传递泛型参数,这也是编译器提示的核心语法问题。 - 附带逻辑bug:原始代码除编译错误外,计数逻辑也存在缺陷:初始计数设置错误、
or_insert不会更新已存在键的值、unwrap存在直接panic的风险,就算修复编译错误也无法得到正确计算结果。
修复方案
- 修正HashMap初始化语句,去掉重复的类型名,使用正确的泛型语法。多数场景下Rust可以自动推导泛型类型,直接写
HashMap::new()即可,不需要手动指定<u8, u8>。 - 调整计数逻辑:初始连续长度设为1(单个元素的连续长度为1),遇到相同元素累加长度,遇到不同元素重置长度为1;使用
entry的and_modify+or_insert组合,键存在时比较更新最大值,不存在时插入初始值。如果只需要保留连续长度大于1的结果,最后过滤掉长度为1的键值对即可。
修复后的完整可运行代码:
use std::collections::HashMap; use std::cmp; fn main() { let data: Vec<u8> = vec![1,1,3,1,1]; let mut counts = HashMap::new(); if data.is_empty() { println!("{:?}", counts); return; } let mut current_count = 1; counts.insert(data[0], 1); for i in 1..data.len() { let x = data[i]; if x == data[i-1] { current_count += 1; counts.entry(x) .and_modify(|v| *v = cmp::max(*v, current_count)) .or_insert(current_count); } else { current_count = 1; counts.entry(x).or_insert(1); } } // 过滤掉连续长度为1的元素,和示例预期输出对齐 counts.retain(|_, v| *v > 1); println!("{:?}", counts); }
运行代码后输出结果为{1: 2},完全符合预期。
内容的提问来源于stack exchange,提问作者gameveloster
相关产品推荐
相关产品推荐

