2013-06-09 16 views
5

Voglio che l'utente passi gli argomenti della riga di comando a una semplice funzione che ho scritto in Rust. So che posso usare int::from_str(args[1]) per convertire, ma questo restituisce un Option<int>, il che significa che per passare a una funzione che prende uno int, come quello qui sotto, devo usare una dichiarazione match. Ma con gli argomenti n, ci sono 2^n possibilità. Scrivere una serie di frasi nidificate su match con qualcosa sarebbe terribile. Sarebbe l'ideale se ci fosse un modo per fare qualcosa di simile:Controlla il tipo di enum di ruggine con un booleano?

// will return either Some(int) or None 
let start = int::from_str(args[1]), end = int::from_str(args[2]); 
if typeof(start) == Some && typeof(end) == Some { 
    println(fmt!("You entered: %d, %d", start, end); 
} else { 
    println("Error with arguments."); 
} 

Esiste un tale metodo? Questo mi permette di provare quale membro di un enum è qualcosa di diverso da match?

risposta

6

Le varianti di un enum sono tutti dello stesso tipo (in questo caso, sia None e Some(foo) sono Option<int>), così che cosa si vuole realmente fare è controllare la variante start e end sono. Fortunatamente Rust offre diverse opzioni.

Una traduzione diretta del codice potrebbe essere quella di utilizzare start.is_some() && end.is_some(). Tuttavia, ciò richiede la modifica della stringa di formato per essere fmt!("You entered: %d, %d", start.get(), end.get()), perché start e end non sono numeri interi, ma sono comunque racchiusi nella variante Some(...). (Questo test delle varianti è qualcosa che deve essere scritto su una base per enum, non ci sono funzioni incorporate che consentono di eseguire il test per qualsiasi enum.)

Il modo più idiomatico sarebbe qualcosa come questo :

// will return either Some(int) or None 
let start_opt = int::from_str(args[1]), end_opt = int::from_str(args[2]); 
match (start_opt, end_opt) { 
    // only matches if both are Some 
    (Some(start), Some(end)) => println(fmt!("You entered: %d, %d", start, end), 

    // will match when either (or both) are None 
    _      => println("Error with arguments."); 
} 
+0

Ah, non sapevo che si potevano fare più argomenti in una partita. È fantastico. Suppongo, quindi, che il metodo 'is_some()', e il suo aspetto, debba essere scritto esplicitamente per qualsiasi tipo là fuori? –

+0

@limp_chimp, corretto, c'è '.is_some()' definito su 'Opzione' nella libreria standard; ma se si definiscono le proprie enumerazioni, non ci saranno automaticamente metodi del genere. – huon

+1

@limp_chimp: e in effetti se si guarda all'implementazione di 'is_some', è'! Self.is_none() ', che è' match * self {None => true, Some (_) => false} '. (Ma non temere un colpo perfetto per le chiamate extra al metodo, queste sono tutte contrassegnate con '# [inline]'.) –

Problemi correlati