2015-06-09 137 views
6

Rust Book上有一个迭代器调用filter()的例子:过滤器(| x |)和过滤器(|&x |)之间有什么区别?

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

下面有一个解释,但我有了解它的麻烦:

This will print all of the even numbers between one and a hundred. (Note that because filter doesn't consume the elements that are being iterated over, it is passed a reference to each element, and thus the filter predicate uses the &x pattern to extract the integer itself.)

但这不起作用:

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

为什么参数封闭引用|&x|,inst ead的|x|?那么使用|&x||x|有什么区别?

据我所知,使用参考|&x|更高效,但我很困惑,因为我不需要使用*x取消引用x指针。

回答

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 

I didn't have to dereference the x pointer by using *x.

那是因为你隐含的间接引用它模式匹配。

I understand that using a reference |&x| is more efficient

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

If so, why does using |x| not throw an error? From my experience with C, I would expect to receive a pointer here.

而且你这样做,在一个参考形式。 x是对(在本例中)i32的参考。

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 

这可以让你不必明确取消对它的引用:但是,%操作是由特质Rem,这是所有对参考/价值实现提供。

Or does Rust implicitly allocate a copy of value of the original x on the stack here?

它强调不做到这一点。事实上,除非迭代项目实施Copy(或可能的Clone,在这种情况下,它也可能是昂贵的),否则将是不安全的。这就是引用被用作闭包参数的原因。

+0

因此'let&x = my_pointer'实际上是'let x = * my_pointer'的替代方法,它也可以在函数参数声明中使用?如果是这样,为什么使用'| x |'不会引发错误?从我与C的经验来看,预计会在这里得到一个指针。或者生锈在这里隐式地分配堆栈中原始'x'的值的副本? – jeremija

+0

哦,我有很多东西要学习:)谢谢 - 现在我对它更清楚了! – jeremija

相关问题