filter(| x |)和filter(|&x |)之间有什么区别?

jer*_*ija 6 closures rust

Rust Book中有一个调用filter()迭代器的例子:

for i in (1..100).filter(|&x| x % 2 == 0) {
    println!("{}", i);
}
Run Code Online (Sandbox Code Playgroud)

下面有一个解释,但我无法理解它:

这将打印一到一百之间的所有偶数.(请注意,因为过滤器不使用正在迭代的元素,所以它会传递对每个元素的引用,因此过滤谓词使用&x模式来提取整数本身.)

然而,这不起作用:

for i in (1..100).filter(|&x| *x % 2 == 0) {
    println!("i={}", i);
}
Run Code Online (Sandbox Code Playgroud)

为什么闭包的参数是参考|&x|,而不是|x|?使用|&x|和有|x|什么区别?

我知道使用引用|&x|更有效,但我很困惑的事实是我不必x通过使用取消引用指针*x.

She*_*ter 8

当用作模式匹配(并且闭包和函数参数也是模式匹配)时,& 绑定到引用,使变量成为解除引用的值.

fn main() {
    let an_int: u8 = 42;
    // Note that the `&` is on the right side of the `:`
    let ref_to_int: &u8 = &an_int; 
    // Note that the `&` is on the left side of the `:`
    let &another_int = ref_to_int;
    let () = another_int;
}
Run Code Online (Sandbox Code Playgroud)

有错误:

error: mismatched types:
 expected `u8`,
    found `()`
Run Code Online (Sandbox Code Playgroud)

如果您查看案例的错误消息,则表示您无法取消引用它,因为它不是引用:

error: type `_` cannot be dereferenced
Run Code Online (Sandbox Code Playgroud)

我没有必要使用*x取消引用x指针.

那是因为你在模式匹配中隐式取消引用它.

我理解使用引用|&x | 效率更高

如果这是真的,那么除了参考之外没有理由使用任何东西!也就是说,引用需要额外的间接来获取真实数据.有一些可衡量的截止点,按值传递项目比传递对它们的引用更有效.

如果是这样,为什么使用|x|不抛出错误?根据我对C的经验,我希望在这里收到一个指针.

你以参考的形式做到了.x是(在这个例子中)的参考i32.但是,%运算符由特征提供,该特征Rem是针对所有参考/值对实现的:

impl Rem<i32> for i32
impl<'a> Rem<i32> for &'a i32
impl<'a> Rem<&'a i32> for i32
impl<'a, 'b> Rem<&'a i32> for &'b i32
Run Code Online (Sandbox Code Playgroud)

这允许您不需要显式取消引用它.

或者Rust会在这里隐式地x在堆栈上分配原始值的副本吗?

它强调并没有做到这一点.实际上,这样做是不安全的,除非实现了迭代的项目Copy(或者可能Clone,在这种情况下,它也可能是昂贵的).这就是引用用作闭包参数的原因.