RustでNoneやエラーに対してデフォルト値・任意の値を返す
RustでOption
のNone
やResult
のエラーErr
に対してデフォルト値・任意の値を返すには、unwrap_or_default
, unwrap_or
, unwrap_or_else
を使う。
型のデフォルト値を返す: unwrap_or_default
unwrap_or_default
はSome
やOk
に対してはその値、None
やエラーErr
に対しては型のデフォルト値を返す。
型のデフォルト値: Defaultトレイト
型のデフォルト値はDefault
トレイトで定められている。
例えば、数値型は0
、ベクタVec
や文字列String
は空のベクタや文字列がデフォルト値となっている。
- f32 - impl Default for f32 - Rust
- Vec - impl<T> Default for Vec<T, Global> in std::vec - Rust
- String - impl Default for String in std::string - Rust
Option::unwrap_or_defaultの例
ベクタVec
からpop
で要素を取り出す。pop
はベクタが空のときNone
を返す。
要素数1個のベクタだと、1回目のpop
はSome
、2回目のpop
はNone
を返す。
unwrap_or_default
を使うと、None
のときは要素の型のデフォルト値が返される。
let mut v: Vec<i32> = vec![100];
assert_eq!(v.pop().unwrap_or_default(), 100);
assert_eq!(v.pop().unwrap_or_default(), 0);
let mut v: Vec<String> = vec![String::from("abc")];
assert_eq!(v.pop().unwrap_or_default(), "abc");
assert_eq!(v.pop().unwrap_or_default(), "");
Result::unwrap_or_defaultの例
文字列をparse
で数値に変換する。parse
は変換できないときエラーを返す。
assert_eq!("100".parse::<i32>().unwrap_or_default(), 100);
assert_eq!("abc".parse::<i32>().unwrap_or_default(), 0);
任意の値を返す: unwrap_or
型のデフォルト値ではなく任意の値を返したいときはunwrap_or
を使う。返したい値を引数に指定する。
Option::unwrap_orの例
let mut v: Vec<i32> = vec![100];
assert_eq!(v.pop().unwrap_or(5), 100);
assert_eq!(v.pop().unwrap_or(5), 5);
文字列String
を返したい場合は次に説明するunwrap_or_else
の使用が推奨されている。
Result::unwrap_orの例
assert_eq!("100".parse::<i32>().unwrap_or(5), 100);
assert_eq!("abc".parse::<i32>().unwrap_or(5), 5);
クロージャ・関数を実行して返す: unwrap_or_else
unwrap_or_else
はNone
やエラーのときに引数に指定したクロージャや関数を実行してその値を返す。
unwrap_or
は先行評価で指定した式が常に実行されるのに対し、unwrap_or_else
は遅延評価でNone
やエラーのときのみ実行される。関数呼び出しの結果を使いたい場合はunwrap_or_else
の使用が推奨されている。
Option::unwrap_or_elseの例
let mut v: Vec<String> = vec![String::from("abc")];
assert_eq!(v.pop().unwrap_or_else(|| String::from("N/A")), "abc");
assert_eq!(v.pop().unwrap_or_else(|| String::from("N/A")), "N/A");
|| ...
は引数なしのクロージャ。
Result::unwrap_or_elseの例
fs::read_to_string
を例とする。パスを指定すると中身を読み込み文字列String
として返す。存在しないパスを指定するとエラーを返す。
存在しないパスに対するunwrap_or_default
とunwrap_or_else
の例を示す。存在するパスの例は省略。
use std::fs;
let path = "path/to/non_existent_file";
assert_eq!(fs::read_to_string(path).unwrap_or_default(), "");
assert_eq!(
fs::read_to_string(path).unwrap_or_else(|_| String::from("N/A")),
"N/A"
);
Result
のunwrap_or_else
は、指定したクロージャや関数に引数としてエラー値(Err(e)
のe
)を渡すので注意。
e
を使わない場合も|_| ...
のように引数を記述する必要がある。