2014-10-10 14 views
6

Her biri sırayla çağıran bir dizi kapakta nasıl yineliyorum? fonksiyonları ileRust'taki bir diziden kapanışların çağrılması

, ben sadece dizide yineleme ve üretilen değerleri kaldırma tarafından bu yapabileceğini keşfetti: Ben kapanışları ile aynı şeyi yapmaya çalıştığınızda,

fn square(x: int) -> int { x * x } 

fn add_one(x: int) -> int { x + 1 } 

fn main() { 
    let funcs = [square, add_one]; 
    for func in funcs.iter() { 
     println!("{}", (*func)(5i)); 
    } 
} 

Ancak, bir hata alıyorum :

fn main() { 
    let closures = [|x: int| x * x, |x| x + 1]; 
    for closure in closures.iter() { 
     println!("{}", (*closure)(10i)); 
    } 
} 

üretir:

<anon>:4:24: 4:34 error: closure invocation in a `&` reference 
<anon>:4   println!("{}", (*closure)(10i)); 
           ^~~~~~~~~~ 
note: in expansion of format_args! 
<std macros>:2:23: 2:77 note: expansion site 
<std macros>:1:1: 3:2 note: in expansion of println! 
<anon>:4:9: 4:41 note: expansion site 
<anon>:4:24: 4:34 note: closures behind references must be called via `&mut` 
<anon>:4   println!("{}", (*closure)(10i)); 
           ^~~~~~~~~~ 
note: in expansion of format_args! 
<std macros>:2:23: 2:77 note: expansion site 
<std macros>:1:1: 3:2 note: in expansion of println! 
<anon>:4:9: 4:41 note: expansion site 

ben yineleme vari ilan çalışırsanız ref mut mümkün, hala çalışmıyor:

fn main() { 
    let closures = [|x: int| x * x, |x| x + 1]; 
    for ref mut closure in closures.iter() { 
     println!("{}", (*closure)(10i)); 
    } 
} 

Sonuçlar içinde:

<anon>:4:24: 4:39 error: expected function, found `&|int| -> int` 
<anon>:4   println!("{}", (*closure)(10i)); 
           ^~~~~~~~~~~~~~~ 
note: in expansion of format_args! 
<std macros>:2:23: 2:77 note: expansion site 
<std macros>:1:1: 3:2 note: in expansion of println! 
<anon>:4:9: 4:41 note: expansion site 

başka dereference eklerseniz:

fn main() { 
    let closures = [|x: int| x * x, |x| x + 1]; 
    for ref mut closure in closures.iter() { 
     println!("{}", (**closure)(10i)); 
    } 
} 

orijinal hata geri almak:

<anon>:4:24: 4:35 error: closure invocation in a `&` reference 
<anon>:4   println!("{}", (**closure)(10i)); 
           ^~~~~~~~~~~ 
note: in expansion of format_args! 
<std macros>:2:23: 2:77 note: expansion site 
<std macros>:1:1: 3:2 note: in expansion of println! 
<anon>:4:9: 4:42 note: expansion site 
<anon>:4:24: 4:35 note: closures behind references must be called via `&mut` 
<anon>:4   println!("{}", (**closure)(10i)); 
           ^~~~~~~~~~~ 
note: in expansion of format_args! 
<std macros>:2:23: 2:77 note: expansion site 
<std macros>:1:1: 3:2 note: in expansion of println! 
<anon>:4:9: 4:42 note: expansion site 

Burada neyi özlüyorum? Bunun nasıl çalıştığını anlatan bir yer var mı?

cevap

7

vektör verim değişmez referanslar arasında .iter() yöntem, böylece siz .iter_mut() kullanmalıdır, kapatma çağırmak değişken olanları gerekir:

fn main() { 
    let mut closures = [|x: int| x * x, |x| x + 1]; 
    for closure in closures.iter_mut() { 
     println!("{}", (*closure)(10i)); 
    } 
} 

----- 

100 
11 
+1

Ah, teşekkürler. Bir kapanmayı immutable olmaya zorlamak için herhangi bir yol var mıdır, böylece problemi çözmek için alternatif bir yol olarak değişebilir bir ref aracılığıyla çağrılmaya ihtiyaç duyulmaz mı? –

+0

Hmm. Bunu yapmak için 'unboxed_closures' özellik geçidini kullanarak denedim,' [| &: x: int | x * x, | &: x: int | x + 1] ', ama inanılmaz bir hata var" hata: eşleşmeyen türleri: beklenen \ 'kapama \', \ 'kapama \' bulundu (beklenen kapatma, kapatma bulundu). Her neyse, orijinal sorumu cevapladın, kutudan çıkarılan kapanma sorununu çözüp çözemeyeceğimi göreceğim. –

+0

@BrianCampbell Ben de buna bakıyordum. Kutusuz kapakların bir sebepten dolayı özellikli olması gibi görünüyor. Bence çıkarım hala buggy. – Levans