Matias Cicero
Matias Cicero

Reputation: 26321

Expected HashSet<&'a str> but found HashSet<&&str>

I'm trying to learn the ropes with Rust, and I was playing around with this little function:

fn anagrams_for<'a>(word: &str, possible_anagrams: &[&'a str]) -> HashSet<&'a str> {
    // count_letters returns a HashMap<char, u32> with occurrence count for each letter
    let letter_count = count_letters(word);
    HashSet::from_iter(possible_anagrams.iter().filter(|anagram| {
        // Basically, if both words have the same letter count, they are anagrams
        letter_count.eq(&count_letters(anagram))
    }))
}

However, when I attempt to build this I get the following error:

error[E0308]: mismatched types
  --> src/lib.rs:15:5
   |
13 |   pub fn anagrams_for<'a>(word: &str, possible_anagrams: &[&'a str]) -> HashSet<&'a str> {
   |                                                                         ---------------- expected `HashSet<&'a str>` because of return type
14 |       let letter_count = count_letters(word);
15 | /     HashSet::from_iter(possible_anagrams.iter().filter(|anagram| {
16 | |         letter_count.eq(&count_letters(anagram))
17 | |     }))
   | |_______^ expected `str`, found `&str`
   |
   = note: expected struct `HashSet<&'a str, RandomState>`
              found struct `HashSet<&&str, _>`

Now, I'm quite lost on what's going on here.

From my ignorant perspective, I can deduce that I'm creating an iterator over a slice over borrowed elements, so I can kind-of understand how, after the filtering, we'd end up with an Iterator<Item=&&str>, but from my understanding Rust should automatically deref that into &str when needed.

So, what's going on here?

Upvotes: 4

Views: 1041

Answers (1)

Gurwinder Singh
Gurwinder Singh

Reputation: 39517

possible_anagrams.iter() produces an iterator of &&str.

Add copied() to iterator to change from iterator of &&str to &str:

From the docs:

This is useful when you have an iterator over &T, but you need an iterator over T.

fn anagrams_for<'a>(word: &str, possible_anagrams: &[&'a str]) -> HashSet<&'a str> {
    // count_letters returns a HashMap<char, u32> with occurrence count for each letter
    let letter_count = count_letters(word);
    HashSet::from_iter(possible_anagrams.iter().copied().filter(|anagram| {
        // Basically, if both words have the same letter count, they are anagrams
        letter_count.eq(&count_letters(anagram))
    }))
}

Upvotes: 5

Related Questions