我想从HashSet<u8>
建立一个Vec<u8>
。我想这样做
2n
记忆,但我唯一可以编译的就是这段...垃圾,我认为两次复制数据并使用3n
内存。
fn vec_to_set(vec: Vec<u8>) -> HashSet<u8> {
let mut victim = vec.clone();
let x: HashSet<u8> = victim.drain(..).collect();
return x;
}
我希望写一些简单的东西,比如:
fn vec_to_set(vec: Vec<u8>) -> HashSet<u8> {
return HashSet::from_iter(vec.iter());
}
但那不会编译:
error[E0308]: mismatched types
--> <anon>:5:12
|
5 | return HashSet::from_iter(vec.iter());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected u8, found &u8
|
= note: expected type `std::collections::HashSet<u8>`
= note: found type `std::collections::HashSet<&u8, _>`
..我真的不明白错误信息,可能是因为我需要RTFM。
因为操作不需要使用矢量¹,我认为它不应该消耗它。这只会导致程序中其他地方的额外复制:
use std::collections::HashSet;
use std::iter::FromIterator;
fn hashset(data: &[u8]) -> HashSet<u8> {
HashSet::from_iter(data.iter().cloned())
}
称之为hashset(&v)
,其中v
是Vec<u8>
或其他强迫切片的东西。
当然有更多的方法来写这个,通用的和所有这些,但这个答案坚持只是介绍我想要关注的事情。
¹这是基于元素类型u8
是Copy
,即它没有所有权语义。
以下应该很好地工作;它符合您的要求:
use std::collections::HashSet;
use std::iter::FromIterator;
fn vec_to_set(vec: Vec<u8>) -> HashSet<u8> {
HashSet::from_iter(vec)
}
from_iter()
适用于实现IntoIterator
的类型,所以Vec
论证就足够了。
补充说明:
return
函数结果;你只需要在其体内的最后一个表达式中省略分号to_iter()
不存在移动数据所有权
let vec: Vec<usize> = vec![1, 2, 3, 4];
let hash_set: HashSet<usize> = vec.into_iter().collect();
克隆数据
let vec: Vec<usize> = vec![1, 2, 3, 4];
let hash_set: HashSet<usize> = vec.iter().cloned().collect();