2014-10-10 4 views
6

Wie iteriere ich über ein Array von Schließungen und rufe sie nacheinander auf?Aufruf von Schließungen von einem Array in Rust

Mit Funktionen, ich entdeckte ich dies nur durch Iteration über das Array tun konnte, und die Werte dereferencing, die produziert:

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

Allerdings, wenn ich versuchen, das gleiche mit Schließungen zu tun, bekomme ich einen Fehler :

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

Produziert:

<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 

Wenn ich die Iteration vari versuchen zu erklären Lage ref mut, es immer noch nicht funktioniert:

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

Ergebnisse in:

<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 

Wenn füge ich eine weitere dereferenzieren:

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

ich wieder auf den ursprünglichen Fehler:

<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 

Was fehlt mir hier? Gibt es irgendwo eine Dokumentation, die beschreibt, wie das funktioniert?

Antwort

7

Die .iter() Methode der Vektor Ausbeuten unveränderlich Referenzen, müssen Sie wandelbar diejenigen die Schließung nennen, so sollten Sie .iter_mut() verwenden:

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, danke. Gibt es eine Möglichkeit, eine Schließung zu erzwingen, die unveränderlich ist, so dass sie nicht über einen veränderlichen Verweis aufgerufen werden muss, als eine alternative Möglichkeit, das Problem zu lösen? –

+0

Hmm. Versucht, das 'unboxed_closures'-Feature-Gate zu verwenden, um dies zu tun, mit '[| &: x: int | x * x, | &: x: int | x + 1] ', hat aber den inksrutable error" error: nicht übereinstimmende Typen: expected \ 'closure \', gefunden \ 'closure \' (erwartete Schließung, gefundene Schließung) ". Wie auch immer, du hast meine ursprüngliche Frage beantwortet. Ich werde sehen, ob ich das Problem mit dem ungelösten Verschluss herausfinden kann. –

+0

@BrianCampbell Ich habe das auch untersucht. Sieht so aus, als ob unverpackte Verschlüsse aus einem bestimmten Grund Feature-Gated sind. Ich denke, die Art der Inferenz ist immer noch fehlerhaft. – Levans

Verwandte Themen