Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I extend a HashSet<String> with another HashSet<String>? [duplicate]

When I try to extend a HashSet<String> with another 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);

I get:

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`

How do I do this?

like image 730
Simon Morgan Avatar asked Mar 02 '23 17:03

Simon Morgan


1 Answers

HashSet::extend() comes from the Extend trait and therefore accepts any iterator (or iterable), not just a set.

If you pass it the reference to a set, that reference is iterable, but the iterator produces references to the elements of the set - in this case &String. Since HashSet::<String>::extend() expects an iterator that produces actual strings, that doesn't compile. There are two ways to fix the issue:

  • by passing the set b to extend by value: a.extend(b);
  • by creating an explicit iterator out of b using b.iter() and cloning the values it produces: a.extend(b.iter().cloned()).

In the first variant, b will be consumed and therefore no longer usable by the caller, but the strings from it will be reused in a. In the second variant, b will remain usable, but its strings will be copied for storage in a.

Note that in neither variant does it make sense to capture the return value of extend(), since it operates by side effect and doesn't return a useful value.

like image 109
user4815162342 Avatar answered Mar 04 '23 07:03

user4815162342