2013-06-09 8 views
5

Chcę, aby użytkownik przekazywał argumenty wiersza poleceń do prostej funkcji, którą napisałem w Rust. Wiem, że mogę użyć int::from_str(args[1]) do konwersji, ale to zwraca Option<int>, co oznacza, że ​​aby przekazać go do funkcji, która ma int, podobnie jak poniżej, muszę użyć instrukcji match. Ale z argumentami n, są 2^n możliwości. Pisanie serii zagnieżdżonych zdań match czymś byłoby straszne. Byłoby idealnie, gdyby istniał sposób na zrobienie czegoś takiego:Sprawdź typ wyliczenia rdzy za pomocą wartości boolowskiej?

// 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."); 
} 

Czy istnieje taka metoda? To pozwala mi przetestować, który członek wyliczenia coś jest poza match?

Odpowiedz

6

Warianty wyliczenia są tego samego typu (w tym przypadku zarówno None i Some(foo)Option<int>), więc to, co rzeczywiście chcesz zrobić, to sprawdzić, który wariant start i end są. Na szczęście Rust oferuje kilka opcji.

Bezpośrednim tłumaczeniem twojego kodu byłoby użycie start.is_some() && end.is_some(). Wymaga to jednak modyfikacji ciągu formatu na fmt!("You entered: %d, %d", start.get(), end.get()), ponieważ start i end nie są liczbami całkowitymi, ale nadal są zawijane w wariancie Some(...). (Ten test wariantowy jest czymś, co musi być napisane na zasadzie per-enum, nie ma wbudowanych funkcji, które pozwalają wykonać test dla dowolnego wyliczenia.)

Bardziej idiomatyczny sposób byłby podobny do tego :

// 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, nie wiedziałem, że możesz zrobić wiele argumentów w meczu. To wspaniale. Rozumiem, że metoda 'is_some()' i jej podobne muszą być napisane wprost dla dowolnego typu? –

+0

@limp_chimp, poprawne, istnieje '.is_some()' zdefiniowane w 'Opcji' w bibliotece standardowej; ale jeśli zdefiniujesz własne wyliczenia, nie będzie automatycznie takich metod. – huon

+1

@limp_chimp: i rzeczywiście, jeśli spojrzysz na implementację 'is_some', to'! Self.is_none() ', która jest' match * self {None => true, Some (_) => false} '. (Ale nie obawiaj się perfekcyjnego trafienia dla dodatkowych wywołań metod, wszystkie są oznaczone "# [inline]".) –

Powiązane problemy