我有一个 HashMap
并且需要获取第一个元素:
type VarIdx = std::collections::HashMap<u16, u8>;
fn get_first_elem(idx: VarIdx) -> u16 {
let it = idx.iter();
let ret = match it.next() {
Some(x) => x,
None => -1,
};
ret
}
fn main() {}
但代码无法编译:
error[E0308]: match arms have incompatible types
--> src/main.rs:5:15
|
5 | let ret = match it.next() {
| _______________^
6 | | Some(x) => x,
7 | | None => -1,
8 | | };
| |_____^ expected tuple, found integral variable
|
= note: expected type `(&u16, &u8)`
found type `{integer}`
note: match arm with an incompatible type
--> src/main.rs:7:17
|
7 | None => -1,
| ^^
我该如何解决?
最佳答案
HashMap
中没有“第一个”项这样的东西。有no guarantees about the order存储值的位置或迭代它们的顺序。
如果顺序很重要,那么也许您可以切换到 BTreeMap
,它保留基于键的顺序。
如果您只需要获取您遇到的第一个值,换句话说任何值,您可以执行与原始代码类似的操作:创建一个迭代器,只取第一个值:
fn get_first_elem(idx: VarIdx) -> i16 {
match idx.values().next() {
Some(&x) => x as i16,
None => -1,
}
}
values()
方法仅在值上创建迭代器。错误的原因是 iter()
将在键和值对上创建一个迭代器,这就是为什么您得到错误 “expected tuple”。
为了让它编译,我不得不改变一些其他的东西:-1
不是一个有效的 u16
值所以它必须变成 i16
,而您的值为 u8
,因此必须转换为 i16
。
作为另一个一般性评论,返回 -1
以指示失败不是很“使用rust ”。这就是 Option
的用途,鉴于 next()
已经返回一个 Option
,这很容易实现:
fn get_first_elem(idx: VarIdx) -> Option<u8> {
idx.values().copied().next()
}
为了将迭代器的 &u8
值转换为 u8
,需要 .copied()
。
关于hashmap - 从 HashMap 获取第一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45194220/