从 Rust 中的向量构建 HashSet

我想用 Vec<u8>做一个 HashSet<u8>,我想做这个

  1. 在一行代码中,
  2. 只复制数据一次,
  3. 只使用 2n内存,

but the only thing I can get to compile is this piece of .. junk, which I think copies the data twice and uses 3n memory.

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。

36512 次浏览

下面的内容应该能够很好地满足您的需求:

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函数结果; 您只需要在它的主体中的最后一个表达式中省略分号

  • 我不确定您使用的是哪个版本的 Rust,但在当前稳定(1.12) to_iter()上不存在

因为操作不需要使用 vector1,所以我认为它是 不应该使用 vector1。这只会导致在程序的其他地方进行额外的复制:

use std::collections::HashSet;
use std::iter::FromIterator;


fn hashset(data: &[u8]) -> HashSet<u8> {
HashSet::from_iter(data.iter().cloned())
}

称之为 hashset(&v),其中 vVec<u8>或其他强制切片的东西。

当然,还有更多的方法来写这个,通用的,但这个答案坚持只介绍我想要关注的东西。

这是基于元素类型 u8Copy,即它没有所有权语义。

移动数据所有权

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();