2015-06-09 21 views
6

bir yineleyici üzerinde filter() çağıran bir örnek vardır: Aşağıdaki bir açıklaması varFiltre (| x |) ve filtre (| & x |) arasındaki fark nedir? <a href="https://doc.rust-lang.org/nightly/book/iterators.html#iterator-adapters" rel="noreferrer">Rust Book</a> yılında

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

ama bunu anlamakta zorlanıyorum:

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.)

Ancak bu işe yaramaz :

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

Neden kapanmasına argümanı referans |&x|, inst olduğunu |x| ead? Ve |&x| ve |x| arasındaki fark nedir?

Ben bir referans |&x| kullanarak daha verimli olduğunu anlıyoruz, ama ben *x kullanarak x pointer KQUEUE yoktu gerçeğiyle şaşkınım. Bir model eşleme olarak kullanılan

cevap

8

& değeri duruma gelmiş değişken hale bir referansa bağlanan (ve kapatılması ve işlev parametresi de desen eşleşir).

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; 
} 

Hata içeriyor:

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

davanız için hata mesajı bakarsanız, o gösterir yapabilirsiniz değil referans olmadığı için, bunun KQUEUE:

Eğer örtülü bunu indirgenmedikleri çünkü var
error: type `_` cannot be dereferenced 

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

desen eşleşmesi.

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

Eğer bu doğruyduysa, o zaman referanslardan başka bir şey kullanmanın bir sebebi olmayacaktır! Yani, referanslar gerçek verilere ulaşmak için ekstra indirekt gerektirir. Değere göre öğelerin geçirilmesi, bunlara yapılan başvurulardan daha verimli olduğu bazı ölçülebilir kesme noktaları vardır.

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

Ve eğer bir referans şeklinde yapın. x, (bu örnekte) bir i32 referansıdır. Bu açıkça bunun KQUEUE gerekmez sağlar

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 

: Ancak % operatör referans/değer tüm çiftleri için uygulanan özelliğin Rem, tarafından sağlanır.

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

değil bunu kesin bir dille yapar. Aslında, yinelenen öğeler Copy (veya potansiyel olarak Clone, bu durumda da pahalı olabilir) uygulanmadığı sürece bunu yapmak güvensiz olacaktır. Bu yüzden referanslar kapatma argümanı olarak kullanılır.

+0

Yani 'let & x = my_pointer' aslında' let x = * my_pointer' yerine bir alternatif ve aynı zamanda işlev parametreleri bildirimlerinde de çalışıyor mu? Eğer öyleyse, '| x |' kullanarak neden bir hata atmıyor? C deneyimimden, burada bir işaretçi almayı beklerdim. Ya da pas, buradaki yığının üzerine orijinal x'in değerinin bir kopyasını örtülü olarak tahsis ediyor mu? – jeremija

+0

Ohhh, öğrenecek çok şeyim var :) Teşekkür ederim - bu benim için şimdi daha net! – jeremija

İlgili konular