我有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,
| ^^
我该如何解决?
答案 0 :(得分:7)
没有&#34;第一&#34; 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()
将在成对的键和值上创建迭代器,这就是您收到错误&#34;期望的元组&#34; 的原因。
要进行编译,我必须更改其他一些内容:-1
不是有效的u16
值,因此必须变为i16
,并且您的值为{{ 1}}所以必须被投射到u8
。
作为另一个一般性评论,返回i16
表示失败不是很严重&#34;生锈&#34;。这是-1
的用途,并且鉴于Option
已经返回next()
,这很容易实现:
Option
为了将迭代器的fn get_first_elem(idx: VarIdx) -> Option<u8> {
idx.values().cloned().next()
}
值转换为.cloned()
,需要&u8
。
答案 1 :(得分:5)
HashMap::iter
返回(&Key, &Value)
对的迭代器。你想要的是HashMap::values
,它产生的迭代器只产生HashMap
的值。
请注意,值的顺序是随机的。它与您将值放入的顺序或与值的实际值无关。