2012-02-14 9 views
10

Il numero tutorial mostra alcuni esempi di corrispondenza del modello, ad esempio la corrispondenza su un numero intero per emulare un'istruzione switch di tipo c. Il tutorial mostra anche come eseguire la destrutturazione di base su un tipo di tupla e strutture destrutturanti.Corrispondenza del modello di ruggine su un vettore

Sembra che dovrebbe essere possibile eseguire la corrispondenza del modello su un vettore, ma non riesco a trovare la sintassi corretta per esso e non ho trovato alcun esempio.

Per esempio, in Haskell si può facilmente destrutturare un elenco:

foldr :: (a -> b -> b) -> b -> [a] -> b 
foldr func initValue []  = initValue 
foldr func initValue (x:xs) = func initValue $ foldr initValue func xs 

Così, guardando una traduzione approssimativa, sarebbe bello essere in grado di fare:

fn foldr<A, B>(func: fn(A, B) -> B, 
       initValue: B, 
       vals: [A]) -> B { 
    alt vals { 
    [] { ret initValue; } 
    _ { 
     let h = vec::head(vals), 
      t = vec::tail(vals); 
     ret foldr(func, func(initValue, h), t); 
    } 
    } 
} 

Note : So che potresti usare una dichiarazione if qui, sto solo usando questo come esempio di pattern matching su un vettore.

questo momento ritorna:

patterns.rs:10:4: 10:5 error: constant contains unimplemented expression type 
patterns.rs:10  [] { ret initValue; } 
       ^
error: aborting due to previous errors 

C'è un esempio nel tutorial per destrutturazione strutture (definita con { .. }) e tuple (definiti con (..)), così sembra che ci dovrebbe essere costruito il supporto anche per i vettori, considerando anche che contengono una sintassi speciale (definita con [ .. ]).

Sentitevi liberi di correggermi se utilizzo i vettori anche nel modo sbagliato.

+0

Un po 'tangenziale, ma per le chiamate di coda si dovrebbe usare "essere" invece di "ret". –

+0

@ ian-b Interessante, il [tutorial] (http://doc.rust-lang.org/doc/tutorial.html) e [riferimento alla lingua] (http://doc.rust-lang.org/doc/ rug.html) sembrano obsoleti, menzionano 'be' come una parola chiave ma non ne fanno un riferimento al momento – ash

risposta

6

Vorrei poter dare più consigli generali su come utilizzare al meglio i pattern matching sui vettori, ma ecco come si possono usare per testare i vettori vuoti (almeno I think è quello che sta facendo il codice Haskell .. .):

use std; 
import std::io::println; 

fn main() { 
    let empty: [int] = []; 
    println(vec_alt(empty)); 
    println(vec_alt([1,2,3])); 
} 

fn vec_alt<A>(vals: [A]) -> str { 
    alt vals { 
     x if x == [] { "empty" } 
     _ { "otherwise" } 
    } 
} 

nota che il tentativo di passare semplicemente [] come argomento riesce perché il compilatore non può dedurre un tipo per il vettore. Sembra che sia possibile passare [()] (un vettore con un nil all'interno) senza prima dichiararlo, ma la dichiarazione alt sembra incapace di testare per vedere se l'espressione di testa corrisponde a [()] (semplicemente passa all'impostazione predefinita).

Tutto sommato, i vettori sembrano un po 'ruvidi al momento. Se c'è un uso specifico che Rust sembra non supportare, gli sviluppatori sono abbastanza aperti a suggerimenti e critiche: https://mail.mozilla.org/listinfo/rust-dev

Vedere anche il manuale di riferimento per una definizione più formale e qualche altro esempio per aiutare a chiarire le cose: http://doc.rust-lang.org/doc/rust.html#alternative-expressions

+4

Penso che alla fine questo non sia supportato al momento. Ho presentato una [RFC per estendere la destrutturazione per supportare i vettori] (https://github.com/mozilla/rust/issues/1844). Ho un altro esempio su quel problema che penso aiuti a mostrare il problema. Sarebbe comunque una bella caratteristica avere. Speriamo che in futuro funzioni come questo. – ash

+0

Qualcuno sta lavorando su questo ora: https://github.com/mozilla/rust/pull/4091 – LennyStackOverflow