简体   繁体   English

如何从 Rust 中的泛型类型的借用数组创建 HashSet?

[英]How can I create a HashSet from a borrowed array of a generic type in Rust?

I have a function taking two borrowed arrays of a generic type T , and I would like to create HashSet s from those arrays so I can compare them.我有一个函数采用两个借用的泛型类型T数组,我想从这些数组创建HashSet ,以便我可以比较它们。

I thought I would be able to do something like this:我以为我可以做这样的事情:

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)
}

But I end up with the following errors:但我最终遇到以下错误:

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>`

Because of the first line in the error, I thought I might be able to solve it like this (I just changed the hashset type to references &T ):由于错误中的第一行,我认为我可以像这样解决它(我只是将 hashset 类型更改为引用&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)
}

But then I see these errors:但后来我看到了这些错误:

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>`

I don't understand how to create new data structures from references to an array.我不明白如何从对数组的引用创建新的数据结构。 Is it the fact that these arrays are borrowed that is the problem, or is it ultimately the trait bound on PartialEq that is the problem?问题是这些数组被借用的事实,还是最终是PartialEq上的特征绑定才是问题?

What if, for whatever reason, I can't modify the function signature, how can I use hashsets to compare the collections?如果出于某种原因,我无法修改函数签名,我该如何使用哈希集来比较集合?

To use HashSet your function needs to have the Eq and Hash trait bounds:要使用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)
}

If you only know that T is PartialEq , then you can implement it like so:如果您只知道TPartialEq ,那么您可以像这样实现它:

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

Other options include T: Ord and use BTreeSet .其他选项包括T: Ord和使用BTreeSet

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM