如何将一个 HashSet<String> 扩展为另一个 HashSet<String>?

6
当我试图使用另一个 HashSet<String> 扩展 HashSet<String> 时:
use std::collections::HashSet;
let mut a = HashSet::new();
a.insert("foo".to_owned());
let mut b = HashSet::new();
b.insert("bar".to_owned());
let c = a.extend(&b);

我理解为:

error[E0271]: type mismatch resolving `<&HashSet<String> as IntoIterator>::Item == String`
 --> src/main.rs:7:11
  |
7 | let c = a.extend(&b);
  |           ^^^^^^ expected reference, found struct `String`
  |
  = note: expected reference `&String`
                found struct `String`

我该如何做这件事?


3
这个问题的已被接受答案没有回答这里提出的问题,因为它建议使用 a.extend(&b),但对于 OP 来说失败了。在另一个答案中它有效是因为另一个答案使用的集合元素是可复制的(Copy)。(我有点惊讶 a.extend(&b) 对于可复制的元素有效,不知道是什么机制实现了它。) - user4815162342
1个回答

10

HashSet::extend() 是来自于 Extend trait,因此接受任何迭代器 (或可迭代对象),而不仅仅是一个 set。

如果你传递给它一个 set 的引用,那个引用将会是可迭代的,但是迭代器产生的将会是指向这个 set 元素的引用 - 在这种情况下是 &String。由于 HashSet::<String>::extend() 需要一个产生实际字符串的迭代器,所以这样并不能编译通过。有两种方法可以解决这个问题:

  • 通过通过值传递 set bextend 函数中: a.extend(b)
  • 通过使用 b.iter() 创建一个显式迭代器,并使用 克隆 它产生的值: a.extend(b.iter().cloned())

在第一种方式中,b 将被消费,因此调用者不再能够使用它,但是其中的字符串将会被重复利用在 a 中。在第二种方式中,b 仍将是可用的,但其中的字符串将被复制以存储在 a 中。

请注意,在这两种方式中都没有意义去捕获 extend() 的返回值,因为它通过副作用操作并且不返回有用的值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接