|
Result列挙型は、正常な値と異常な場合の値(エラー内容)のいずれかを保持する列挙型。
Result列挙型はstd::preludeに含まれているので、useしなくても使える。
Resultインスタンスを作るには、正常な場合はOkを使い、エラーの場合はErrを使う。
// 正常な場合 let r: Result<i32, &str> = Ok(123); println!("{:?}", r); // エラーを返す場合 let r: Result<i32, &str> = Err("エラー!"); println!("{:?}", r);
match r { Ok(n) => println!("ok = {}", n), Err(message) => println!("error = {}", message), }
クレート独自のResultを定義してそれを使うということもよく行われるようだ。[2024-10-07]
→独自Resultを定義する例
自分の関数(やメソッド)の戻り型がResultで、自分の関数内から呼び出している関数の戻り型もResultのとき、Errが返ってきたらそのErrをそのまま自分の呼び出し元に返したいことがある。
これを素直にコーディングすると以下のようになる。
fn func1() -> Result<i32, String> { let r = func2(); let n = match r { Ok(n) => n, Err(e) => return Err(e), // エラーのときはエラーを返す }; Ok(n + 1) }
fn func2() -> Result<i32, String> { Err(String::from("エラーの実験")) }
?演算子を使うと、この処理を簡単に記述することが出来る。
fn func1() -> Result<i32, String> { let n = func2()?; Ok(n + 1) }
?演算子は、Okのときはそれが保持している値を返し、ErrのときはErrをreturnする。
Errをreturnする(Errが関数の戻り値になる)ので、自分の関数の戻り型がResultでないと使えない。
ちなみに、?演算子は関数やメソッド呼び出しで使われることが多いが、変数に対しても使える。
let r = func2(); let n = r?;
Rustでは演算子をオーバーロードすることが出来る。(自分の構造体で加算「+」とか減算「-」とかを使うことが出来るようになる)
そのために、演算子とそれに対応するトレイトが決められており、そのトレイトを実装すれば対応する演算子が使えるようになる。
→演算子とトレイトの対応関係:core::ops
?演算子にはTryトレイトが対応しており、Result列挙型はTryトレイトを実装している。
Result<T, E>のメソッド(抜粋)。[2024-10-06]
メソッド | 説明 | 例 |
---|---|---|
is_ok(&self) -> bool |
Okかどうか。 | let ok: Result<i32, &str> = Ok(123); |
is_ok_and(self, f:
impl FnOnce(T) -> bool) -> bool |
Okのときはfを実行してその結果を返す。 Errのときはfalseを返す。 |
let ok: Result<i32, &str> = Ok(123); |
is_err(&self) -> bool |
Errかどうか。 | let ok: Result<i32, &str> = Ok(123); |
is_err_and(self,
f: impl FnOnce(E) -> bool) -> bool |
Errのときはfを実行してその結果を返す。 Okのときはfalseを返す。 |
let ok: Result<i32, &str> = Ok(123); |
expect(self, msg:
&str) -> T |
Okのときは値(と所有権)を返す。 Errのときはメッセージ付きのパニックを起こす。 |
let result: Result<i32, &str> = Ok(123); |
unwrap(self) -> T |
Okのときは値(と所有権)を返す。 Errのときはパニックを起こす。 →?演算子 |
let result: Result<i32, &str> = Ok(123); |
unwrap_or(self,
default: T) -> T |
Okのときは値(と所有権)を返す。 Errのときは引数defaultの値を返す。 |
let ok: Result<i32, &str> = Ok(123); |
unwrap_or_default(self)
-> T |
Okのときは値(と所有権)を返す。 ErrのときはTのデフォルト値を返す。 TがDefaultトレイトを実装しているとき(デフォルト値を返せるとき)だけ使用可能。 |
let ok: Result<i32, &str> = Ok(123); |
unwrap_or_else<F:
FnOnce(E) -> T>(self, op: F) -> T |
||
unwrap_unchecked(self)
-> T |
||
unwrap_err_unchecked(self) -> E |
||
expect_err(self,
msg: &str) -> E |
Errのときはエラーの値(と所有権)を返す。 Okのときはメッセージ付きのパニックを起こす。 |
|
unwrap_err(self)
-> E |
Errのときはエラーの値(と所有権)を返す。 Okのときはパニックを起こす。 |
|
as_ref(&self) ->
Result<&T, &E> |
||
as_mut(&mut self) ->
Result<&mut T, &mut E> |
||
map<U, F>(self, op: F)
-> Result<U, E> |
Result<T, E>をResult<U, E>に変換する。 (Okの型をTからUに変換する) |
let r1: Result<i32, &str> = Ok(123); |
map_or<U, F>(self,
default: U, f: F) -> U |
||
map_or_else<U,
D, F>(self, default: D, f: F) -> U |
||
map_err<F, O>(self,
op: O) -> Result<T, F> |
Result<T, E>をResult<T, F>に変換する。 (Errの型をEからFに変換する) |
let r1: Result<i32, &str> = Err("error"); |
inspect<F:
FnOnce(&T)>(self, f: F) -> Self |
||
inspect_err<F:
FnOnce(&E)>(self, f: F) -> Self |
||
ok(self) ->
Option<T> |
Result<T, E>をOption<T>に変換する。 OkはSome、ErrはNoneになる。 |
let ok: Result<i32, &str> = Ok(123); |
err(self) ->
Option<E> |
Result<T, E>をOption<E>に変換する。 OkはNone、ErrはSomeになる。 |
let ok: Result<i32, &str> = Ok(123); |
as_deref(&self) ->
Result<&T::Target, &E> |
||
as_deref_mut(&mut
self) -> Result<&mut T::Target, &mut E> |
||
iter(&self) -> Iter<'_,
T> |
||
iter_mut(&mut self)
-> IterMut<'_, T> |
||
into_ok(self) -> T |
||
into_err(self) -> E |
||
and<U>(self, res:
Result<U, E>) -> Result<U, E> |
||
and_then<U,
F>(self, op: F) -> Result<U, E> |
||
or<F>(self, res:
Result<T, F>) -> Result<T, F> |
||
or_else<F, O>(self,
op: O) -> Result<T, F> |