Result
のmap
前の例で見たmultiply
でのパニックは、コードを強固にするためには書きません。一般に、呼び出した側がエラーをどのように対処するべきかを自由に決められるように、エラーを呼び出した場所に返すのが好ましいです。
まずは、どのようなエラー型を扱っているのかを知る必要があります。Err
型を定めるために、i32
に対しFromStr
トレートを使って実装されたparse()
を見てみましょう。結果、Err
型はParseIntError
というものであることが分かります。
以下の例では、単純なmatch
文が全体として扱いづらいコードにしています。
use std::num::ParseIntError; // With the return type rewritten, we use pattern matching without `unwrap()`. // リターン型を再度記述することで、パターンマッチングを`unwrap()`なしで行います。 fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> { match first_number_str.parse::<i32>() { Ok(first_number) => { match second_number_str.parse::<i32>() { Ok(second_number) => { Ok(first_number * second_number) }, Err(e) => Err(e), } }, Err(e) => Err(e), } } fn print(result: Result<i32, ParseIntError>) { match result { Ok(n) => println!("n is {}", n), Err(e) => println!("Error: {}", e), } } fn main() { // This still presents a reasonable answer. // ここは以前と変わらず、妥当な解を与えます。 let twenty = multiply("10", "2"); print(twenty); // The following now provides a much more helpful error message. // こちらは今度は有益なエラーメッセージを与えます。 let tt = multiply("t", "2"); print(tt); }
幸運にも、Option
のmap
、and_then
、その他多くのコンビネータもResult
のために実装されています。Result
に全てのリストが記載されています。
use std::num::ParseIntError; // As with `Option`, we can use combinators such as `map()`. // This function is otherwise identical to the one above and reads: // Modify n if the value is valid, otherwise pass on the error. // `Option`と同様、`map()`などのコンビネータを使うことができます。 // この関数は`map()`を使っている点以外は上記の関数と同じで、 // 値が有効ならnを変更し、無効であればエラーをそのまま見送ります。 fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> { first_number_str.parse::<i32>().and_then(|first_number| { second_number_str.parse::<i32>().map(|second_number| first_number * second_number) }) } fn print(result: Result<i32, ParseIntError>) { match result { Ok(n) => println!("n is {}", n), Err(e) => println!("Error: {}", e), } } fn main() { // This still presents a reasonable answer. // ここは以前と変わらず、妥当な解を与えます。 let twenty = multiply("10", "2"); print(twenty); // The following now provides a much more helpful error message. // こちらは今度は有益なエラーメッセージを与えます。 let tt = multiply("t", "2"); print(tt); }