2015-06-09 177 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

相關問題