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

时间:2016-01-27 06:41:24

标签: iterator rust move-semantics

我可以写出以下两种方式,第二种方式受What is the idiomatic way to create a collection of references to methods that take self?启发:

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中转换成(通常是内联的)函数调用,但是我喜欢在第二行中引用函数的清晰度如果没有克隆就可以使用它。

2 个答案:

答案 0 :(得分:5)

Iterator有一个cloned方法,相当于.map(|x| x.clone()),如果Copy类型相当于.map(|&x| x)。这样你就可以写

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

答案 1 :(得分:2)

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

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

    // [...]

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