NebulaFox
NebulaFox

Reputation: 8323

Cannot coerce HashSet<&str> into HashSet<&String>

While messing around with some example code, I found I could not coerce HastSet<&String> into HashSet<&str> or vice versa.

use std::collections::HashSet;

fn main() {
    // move strings into HashSet
    let known_values: HashSet<&str> = ["a", "b", "c"]
        .iter().cloned().collect();

    // provided an Vec<String>
    let provided_values: Vec<String> = vec![
        "a".to_string(),
        "b".to_string(),
        "z".to_string()
    ];

    // hash set of refrences
    let mut found: HashSet<&String> = HashSet::new();
    found.insert(&provided_values[0]);
    found.insert(&provided_values[1]);
    found.insert(&provided_values[2]);

    //let missing = known_values.difference(&found);
    let missing = found.difference(&known_values);

    println!("missing: {:#?}", missing);
}

(Playground)

Compiler Error

error[E0308]: mismatched types
  --> src/main.rs:23:36
   |
23 |     let missing = found.difference(&known_values);
   |                                    ^^^^^^^^^^^^^ expected struct `std::string::String`, found `str`
   |
   = note: expected reference `&std::collections::HashSet<&std::string::String>`
              found reference `&std::collections::HashSet<&str>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

I know you can coerce &String into &str and vice versa, so I am a little surprised it did not extend to HashSet<&String> and HashSet<&str>. What ways are there to get around this without just allocating Strings?

Upvotes: 0

Views: 117

Answers (1)

John Kugelman
John Kugelman

Reputation: 361977

There's no need to have a different type of HashSet. Change found to a HashSet<&str> and the program works.

// hash set of references
let mut found: HashSet<&str> = HashSet::new();
found.insert(&provided_values[0]);
found.insert(&provided_values[1]);
found.insert(&provided_values[2]);

(Playground)

Upvotes: 2

Related Questions