从Rust中的向量构建HashSet

eivgtgni  于 2023-01-30  发布在  其他
关注(0)|答案(3)|浏览(229)

我想从一个Vec<u8>生成一个HashSet<u8>。我想这样做
1.在一行代码中,
1.仅复制数据一次,
1.仅使用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。

mgdq6dx1

mgdq6dx11#

因为这个操作不需要消耗向量¹,所以我认为它 * 不应该 * 消耗它,这只会导致在程序的其他地方进行额外的复制:

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,即它没有所有权语义。

rqqzpn5f

rqqzpn5f2#

下面的代码应该可以很好地工作;它满足您的要求:

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()不存在
ahy6op9u

ahy6op9u3#

正在将Vec转换为HashSet

移动数据所有权

let vec: Vec<u8> = vec![1, 2, 3, 4];
let hash_set: HashSet<u8> = vec.into_iter().collect();

克隆数据

let vec: Vec<u8> = vec![1, 2, 3, 4];
let hash_set: HashSet<u8> = vec.iter().cloned().collect();

相关问题