在std::iter::Iterator::filter()的文档中,它说明了值是通过引用传递给闭包的,并且由于许多迭代器会生成引用,因此在这种情况下,传递的值就是对引用的引用。通过使用&x
模式删除一个间接级别,或使用&&x
模式删除两个间接级别,它提供了一些改善人体工程学的建议。
但是,如果要迭代的项目未实现Copy
,我发现第二种模式不会编译:
#[derive(PartialEq)]
struct Foo(i32);
fn main() {
let a = [Foo(0), Foo(1), Foo(2)];
// This works
let _ = a.iter().filter(|&x| *x!=Foo(1));
// This also works
let _ = a.iter().filter(|&x| x!=&Foo(1));
// This does not compile
let _ = a.iter().filter(|&&x| x!=Foo(1));
}
您得到的错误是:
19 | let _ = a.iter().filter(|&&x| x!=Foo(1));
| ^^-
| | |
| | data moved here
| | move occurs because `x` has type `Foo`, which does not implement the `Copy` trait
| help: consider removing the `&`: `&x`
这是否意味着如果我使用&&x
解构模式,并且值是Copy
,Rust会静默复制我要遍历的每个值?如果是这样,为什么会发生?
在Rust中,函数或闭包参数是不可辩驳的模式。