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

时间:2015-06-09 18:27:34

标签: closures rust

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

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

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

  

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

然而,这不起作用:

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

为什么闭包的参数是引用|&x|,而不是|x|?使用|&x||x|之间的区别是什么?

我知道使用引用|&x|会更有效率,但我对我不必使用{{1 }}

1 个答案:

答案 0 :(得分: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;
}

有错误:

error: mismatched types:
 expected `u8`,
    found `()`

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

error: type `_` cannot be dereferenced
  

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

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

  

我理解使用引用|&amp; 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

这使您无需明确取消引用它。

  

或者,Rust会在堆栈中隐式分配原始x的值副本吗?

强调这样做。实际上,这样做是不安全的,除非迭代项目实现Copy(或可能Clone,在这种情况下它也可能很昂贵)。这就是引用被用作闭包参数的原因。