What is an idiomatic way to collect an iterator of &T into a collection of Ts?

前端 未结 2 1530
情歌与酒
情歌与酒 2020-12-19 10:55

I need to collect an iterator over a slice of &strs into a collection of &strs. The problem is that the iterator yields &&str

相关标签:
2条回答
  • 2020-12-19 11:31

    If T implements Copy then you can use Iterator::copied. Otherwise, if it implements Clone then you can use Iterator::cloned. Like any immutable reference, &str implements both Clone and Copy, so you can use copied:

    let hashset: HashSet<&str> = words.iter().copied().collect();
    
    0 讨论(0)
  • 2020-12-19 11:42

    Is a bicycle an idiomatic way to get from one city to another? Like most things in software (and life), it depends.

    If your type implements Copy

    I'd prefer these in this order:

    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())

    If your type implements Clone

    I'd prefer these in this order:

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

    If your type doesn't implement Copy or Clone

    Then you cannot trivially create an owned value. The type may implement ToOwned or there may be a bespoke function or method that you can call inside of map, or you may simply not be able to do anything.


    In your case, I'd use words.iter().copied().collect::<HashSet<_>>().

    See also:

    • Iterating over a slice's values instead of references in Rust?
    • What's the idiomatic way to copy from a primitive type reference by value?
    • Why is "&&" being used in closure arguments?
    • Why does the argument for the find closure need two ampersands?
    0 讨论(0)
提交回复
热议问题