diff --git a/src/error/multiple_error_types/reenter_question_mark.md b/src/error/multiple_error_types/reenter_question_mark.md index a94c0f8e5..a3a4bdb97 100644 --- a/src/error/multiple_error_types/reenter_question_mark.md +++ b/src/error/multiple_error_types/reenter_question_mark.md @@ -1,32 +1,45 @@ -# Other uses of `?` +# `?`の他の活用法 + +以前の例では`parse`の呼び出しに対するその場での対応として、エラーをライブラリのエラーからboxされたエラーへと`map`していました。 ```rust,ignore .and_then(|s| s.parse::() .map_err(|e| e.into()) ``` + +簡単でよくあるオペレーションのため、可能なら省略してしまえると便利だったでしょう。でも残念、`and_then`が十分にフレキシブルでないため、それはできません。ただその代わり、`?`なら使えます。 + +`?`の挙動は、`unwrap`または`return Err(err)`として説明されていました。これはほぼ正解で、本当は`unwrap`、もしくは`return Err(From::from(err))`という意味があります。`From::from`は異なる型の間での変換ユーティリティであることから、エラーがリターン型に変換可能な場合に`?`を使うことで、その変換を自動的に行ってくれます。 + +前の例を`?`を使ったものに書き換えてみましょう。その結果、`From::from`がエラー型に実装されている時`map_err`は消えてなくなります。 ```rust,editable use std::error; use std::fmt; // Change the alias to `Box`. +// エイリアスを`Box`に変換する。 type Result = std::result::Result>; #[derive(Debug)] @@ -45,12 +58,15 @@ impl error::Error for EmptyVec { fn cause(&self) -> Option<&error::Error> { // Generic error, underlying cause isn't tracked. + // 基本となるエラー、原因は記録されていない。 None } } // The same structure as before but rather than chain all `Results` // and `Options` along, we `?` to get the inner value out immediately. +// 前と同じ構造だが、`Results`と`Option`を繋げていくより、 +// `?`で内部の値をその場で取得します。 fn double_first(vec: Vec<&str>) -> Result { let first = vec.first().ok_or(EmptyVec)?; let parsed = first.parse::()?; @@ -75,14 +91,17 @@ fn main() { } ``` + +これでかなり綺麗になりました。元の`panic`と比べ、リターン型が`Result`であることを除けば、`unwrap`の呼び出しを`?`で置き換える点で非常に似ています。結果、最も上のレベルで分解されなければなりません。 -### See also: +### 参考: -[`From::from`][from] and [`?`][q_mark] +[`From::from`][from] と [`?`][q_mark] [from]: https://doc.rust-lang.org/std/convert/trait.From.html [q_mark]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator