非破坏性地迭代 Rust 集合,但不是通过引用

Non-destructively iterating over a Rust collection, but not by reference

我可以写成下面两种方式,第二种是受到的启发:

channels.iter().flat_map(|c|c.to_uppercase()).collect(),
channels.clone().into_iter().flat_map(char::to_uppercase).collect(),

第二行必须克隆集合,因为 char::to_uppercase 不接受引用作为参数,.iter() 提供引用并且 .into_iter() 移动集合。

有没有不需要克隆集合或创建闭包的方法来做到这一点?我不讨厌闭包,我保证,而且我知道它们只是在 LLVM 中变成了(通常是内联的)函数调用,但我喜欢在第二行中引用函数的简洁性,并且更愿意使用它如果没有克隆就可以完成。

您可以定义一个接受引用的函数。如果你想让它接近它的用法,你甚至可以把它放在另一个函数中。

fn foobar() {
    fn to_uppercase(c: &char) -> ::std::char::ToUppercase {
        c.to_uppercase()
    }

    // [...]

    let channels_upper = channels.iter().flat_map(to_uppercase).collect();
}

Iterator 有一个 cloned 方法等同于 .map(|x| x.clone()),在 Copy 类型的情况下等同于 .map(|&x| x)。这样就可以写

channels.iter().cloned().flat_map(char::to_uppercase).collect()