Rust中HashSet类型不匹配问题:期望HashSet<&'a str>却得到HashSet<&&str>
解决Rust变位词函数的类型不匹配问题
嘿,这个问题我之前也踩过坑!让我帮你把来龙去脉理清楚:
问题核心
你的报错已经说得很明确了:你声明的返回类型是HashSet<&'a str>,但实际生成的是HashSet<&&str>。原因在于:
possible_anagrams是一个&[&'a str]类型的切片(对&str数组的引用)- 调用
.iter()遍历这个切片时,迭代器产生的元素是切片中每个元素的引用,也就是&&'a str(相当于对&str再套一层引用)
为什么自动解引用没生效?
你提到的Rust自动解引用(Deref coercion)确实存在,但它的生效场景是有限的:当你把一个类型传递给需要另一个可解引用类型的函数参数时,Rust会自动帮你解引用。比如你的count_letters(anagram),这里anagram是&&str,而count_letters接受&str,所以自动解引用生效了,这部分没问题。
但HashSet::from_iter是泛型函数,它会严格依据迭代器的Item类型来创建集合。这里迭代器的Item是&&str,所以生成的集合就是HashSet<&&str>,和你声明的返回类型不兼容,Rust不会在这里自动帮你做解引用转换。
解决方法
有两种简单的方式把&&str转换成&str,适配返回类型:
方法1:使用cloned()
cloned()会对迭代器中的每个元素克隆一份,对于&&str来说,克隆就是复制底层的&str引用(非常廉价,没有性能开销):
fn anagrams_for<'a>(word: &str, possible_anagrams: &[&'a str]) -> HashSet<&'a str> { let letter_count = count_letters(word); HashSet::from_iter(possible_anagrams.iter().filter(|anagram| { letter_count.eq(&count_letters(anagram)) }).cloned()) // 加上cloned()转换类型 }
方法2:使用copied()
因为&str实现了Copy trait,你也可以用copied()来代替cloned(),效果完全一样,语义上更明确(表示复制一个Copy类型):
fn anagrams_for<'a>(word: &str, possible_anagrams: &[&'a str]) -> HashSet<&'a str> { let letter_count = count_letters(word); HashSet::from_iter(possible_anagrams.iter().filter(|anagram| { letter_count.eq(&count_letters(anagram)) }).copied()) // 使用copied() }
这样修改后,迭代器的Item类型就变成了&'a str,和返回类型匹配,编译就能通过啦!
内容的提问来源于stack exchange,提问作者Matias Cicero
相关产品推荐
相关产品推荐

