将&T的迭代器收集到T的集合中的惯用方式是什么?

时间:2019-08-21 14:15:23

标签: reference rust iterator

我需要将&str的切片上的迭代器收集到&str的集合中。问题在于迭代器产生&&str s。

我尝试从&word映射到word,尽管它可以正常工作,但我不知道它是否被认为是好的,或者是否有更好的选择。

问题:

use std::collections::HashSet;

fn main() {
    let words = &["hello", "world", "I'm", "a", "Rustacean!"];
    let hashset = words.iter().collect::<HashSet<&str>>();
}

Playground

error[E0277]: a collection of type `std::collections::HashSet<&str>` cannot be built from an iterator over elements of type `&&str`
 --> src/main.rs:5:32
  |
5 |     let hashset = words.iter().collect::<HashSet<&str>>();
  |                                ^^^^^^^ a collection of type `std::collections::HashSet<&str>` cannot be built from `std::iter::Iterator<Item=&&str>`
  |
  = help: the trait `std::iter::FromIterator<&&str>` is not implemented for `std::collections::HashSet<&str>`

我的解决方案:

use std::collections::HashSet;

fn main() {
    let words = &["hello", "world", "I'm", "a", "Rustacean!"];
    let hashset = words.iter().map(|&w| w).collect::<HashSet<&str>>();
}

Playground

2 个答案:

答案 0 :(得分:9)

如果T实现了Copy,则可以使用Iterator::copied。否则,如果它实现Clone,则可以使用Iterator::cloned。像任何不可变的引用一样,&str同时实现CloneCopy,因此您可以使用copied

let hashset: HashSet<&str> = words.iter().copied().collect();

答案 1 :(得分:9)

自行车是从一个城市到达另一个城市的惯用方式吗?像软件(和生活)中的大多数事物一样,它取决于

如果您的类型实现了Copy

我希望这些顺序排列:

  1. some_iter.copied()
  2. some_iter.cloned()
  3. some_iter.map(|&v| v)
  4. some_iter.map(|v| *v)
  5. some_iter.map(Clone::clone)
  6. some_iter.map(|v| v.clone())

如果您的类型实现了Clone

我希望这些顺序排列:

  1. some_iter.cloned()
  2. some_iter.map(Clone::clone)
  3. some_iter.map(|v| v.clone())

如果您的类型未实现CopyClone

然后,您将无法轻松创建拥有的价值。该类型可能实现ToOwned,或者可能在map内部调用定制的函数或方法,或者您可能根本无能为力。


在您的情况下,我将使用words.iter().copied().collect::<HashSet<_>>()

另请参阅: