首页 > 解决方案 > 如何从 Rust 中借用的泛型数组创建 HashSet?

问题描述

我有一个函数采用两个借用的泛型数组T,我想HashSet从这些数组中创建 s 以便我可以比较它们。

我以为我可以做这样的事情:

pub fn sublist<T: PartialEq>(first_list: &[T], second_list: &[T]) -> bool {
  let first_set: HashSet<T> = first_list.iter().collect();
  let second_set: HashSet<T> = second_list.iter().collect();

  first_set.is_subset(&second_set)
}

但我最终遇到以下错误:

a value of type `std::collections::HashSet<T>` cannot be built from an iterator over elements of type `&T`

value of type `std::collections::HashSet<T>` cannot be built from `std::iter::Iterator<Item=&T>`

help: the trait `std::iter::FromIterator<&T>` is not implemented for `std::collections::HashSet<T>`

由于错误中的第一行,我认为我可以像这样解决它(我只是将 hashset 类型更改为 references &T):

pub fn sublist<T: PartialEq>(first_list: &[T], second_list: &[T]) -> bool {
  let first_set: HashSet<&T> = first_list.iter().collect();
  let second_set: HashSet<&T> = second_list.iter().collect();

  first_set.is_subset(&second_set)
}

但后来我看到这些错误:

the trait bound `T: std::cmp::Eq` is not satisfied

the trait `std::cmp::Eq` is not implemented for `T`

note: required because of the requirements on the impl of `std::cmp::Eq` for `&T`
note: required because of the requirements on the impl of `std::iter::FromIterator<&T>` for `std::collections::HashSet<&T>`

我不明白如何从对数组的引用创建新的数据结构。是这些数组被借用的事实是问题,还是最终PartialEq是问题绑定的特征?

如果无论出于何种原因,我无法修改函数签名,我该如何使用哈希集来比较集合?

标签: rust

解决方案


要使用HashSet您的函数,需要具有EqHash特征界限:

use std::hash::Hash;
use std::collections::HashSet;

pub fn sublist<T: Eq + Hash>(first_list: &[T], second_list: &[T]) -> bool {
  let first_set: HashSet<&T> = first_list.iter().collect();
  let second_set: HashSet<&T> = second_list.iter().collect();

  first_set.is_subset(&second_set)
}

如果您只知道Tis PartialEq,那么您可以像这样实现它:

pub fn sublist<T: PartialEq>(first_list: &[T], second_list: &[T]) -> bool {
    first_list.iter().all(|v| second_list.contains(v))
}

其他选项包括T: Ord和使用BTreeSet.


推荐阅读