2013-06-09 4 views
5

私はRustで書いた簡単な関数にコマンドライン引数を渡して欲しい。私はint::from_str(args[1])を使用して変換することができますが、これはOption<int>を返します。これは、を受け取る関数に渡すために、私はmatchステートメントを使用する必要があります。しかし、n引数では、2^nの可能性があります。一連のネストされたmatchステートメントを何かに書くことはひどいことになります。ブール値で錆の列挙型をチェックしますか?

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

このような方法はありますか?これにより、en30のメンバーがmatch以外であるかどうかテストできますか?列挙型の

答えて

6

変異体が(両NoneSome(foo)Option<int>あり、この場合は)すべて同じタイプなので、あなたが実際に何をしたいのかstartendがあるバリアントチェックです。幸いにもRustにはいくつかのオプションがあります。

コードを直接翻訳する場合は、start.is_some() && end.is_some()を使用します。しかし、startendは整数ではありませんが、まだSome(...)バリアントにラップされているため、フォーマット文字列をfmt!("You entered: %d, %d", start.get(), end.get())に変更する必要があります。 (このバリアントテストは、列挙型ベースで記述されなければならないものです。任意の列挙型のテストを実行できるようなビルドイン関数はありません)。

もっと慣用的な方法は、 :

// 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

ああ、私はあなたが試合で複数の議論を行うことができないことを知りました。それは素晴らしいことです。私は 'is_some()'メソッドなどを明示的に書く必要があります。 –

+0

@limp_chimp、correct、標準ライブラリの 'Option'に' .is_some() 'が定義されています。独自の列挙型を定義すると、自動的にそのようなメソッドはありません。 – huon

+1

@limp_chimp:実際に 'is_some'の実装を見ると'!self.is_none() 'となり、' match * self {None => true、Some(_)=> false} 'となります。 (しかし、余分なメソッド呼び出しのための完全なヒットのための恐れはありません;これらはすべて '#[inline]'とマークされています)。 –

関連する問題