迭代切片的值而不是Rust中的引用?

ide*_*n42 13 iterator rust

当循环遍历一个结构片段时,我得到的值是一个引用(这很好),但是在某些情况下,必须var(*var)在很多地方一样编写它是很烦人的.

有没有更好的方法来避免重新声明变量?

fn my_fn(slice: &[MyStruct]) {
    for var in slice {
        let var = *var;  // <-- how to avoid this?

        // Without the line above, errors in comments occur:

        other_fn(var);  // <-- expected struct `MyStruct`, found reference

        if var != var.other {
            // ^^ trait `&MyStruct: std::cmp::PartialEq<MyStruct>>` not satisfied
            foo();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请参阅:实际错误输出(更加神秘).

Luk*_*odt 27

您可以通过模式中的解构来删除引用:

//  |
//  v
for &var in slice {
    other_fn(var);
}
Run Code Online (Sandbox Code Playgroud)

但是,这只适用Copy-types!如果你有非Copy,但只是Clone类型,你可以使用cloned()迭代器适配器; 有关更多信息,请参阅Chris Emerson的答案.如果您的类型不是Clone,则您没有机会这样做.


Chr*_*son 13

在某些情况下,如果可以使用迭代,则可以直接迭代值,例如使用Vec::into_iter().使用切片,您可以使用cloned:

fn main() {
    let v = vec![1, 2, 3];
    let slice = &v[..];
    for u in slice.iter().cloned() {
        let u: usize = u; // prove it's really usize, not &usize
        println!("{}", u);
    }
}
Run Code Online (Sandbox Code Playgroud)

这显然依赖于可克隆的项目; 但如果没有,你可能确实想要参考.

  • @EliSadoff实际上,我们的两个解决方案都可能会产生相同的优化装配输出.不是克隆完整的切片或迭代器,而是生成每个元素. (2认同)