Rust

Rust Resultの使い方

失敗する可能性を型で表し、呼び出し側へ安全に伝えるエラー処理を学びます。

Rust入門の講座一覧

01

Resultは成功か失敗かを表す

Result<T, E>は、成功した値をOk(T)、失敗の情報をErr(E)で包みます。例外を暗黙に投げるのではなく、戻り値から失敗の可能性を読み取れます。

年齢を変換するRUST
fn parse_age(text: &str) -> Result<u32, std::num::ParseIntError> {
    text.parse()
}

fn main() {
    println!("{:?}", parse_age("20"));
    println!("{:?}", parse_age("abc"));
}
実行結果OUTPUT
Ok(20)
Err(ParseIntError { kind: InvalidDigit })
02

matchで成功と失敗を分ける

matchを使うと、OkErrそれぞれに処理を書けます。

入力エラーを表示するRUST
fn parse_age(text: &str) -> Result<u32, std::num::ParseIntError> {
    text.parse()
}

fn main() {
    match parse_age("abc") {
        Ok(age) => println!("{age}歳"),
        Err(error) => println!("入力エラー: {error}"),
    }
}
実行結果OUTPUT
入力エラー: invalid digit found in string
03

unwrap_orと?演算子

失敗時の代替値が決まっているならunwrap_orが使えます。処理を呼び出し元へ返したい場合は?演算子が便利です。

失敗時の既定値RUST
fn main() {
    let age = "abc".parse::<u32>().unwrap_or(0);
    println!("{age}歳");
}
実行結果OUTPUT
0歳
?でエラーを返すRUST
fn add_ages(left: &str, right: &str) -> Result<u32, std::num::ParseIntError> {
    let left_age = left.parse::<u32>()?;
    let right_age = right.parse::<u32>()?;
    Ok(left_age + right_age)
}

?は失敗したらその場でErrを返し、成功したら中身の値を取り出します。使う関数自身がResultを返す必要があります。

04

Optionとの違い

Option<T>は「値があるかないか」、Result<T, E>は「成功したか、どのように失敗したか」を表します。

最初の単語を探すRUST
fn first_word(text: &str) -> Option<&str> {
    text.split_whitespace().next()
}

fn main() {
    println!("{}", first_word("").unwrap_or("単語なし"));
}
実行結果OUTPUT
単語なし
05

練習

2つの文字列を数値へ変換して足し算する関数を作り、片方が数字でない場合にErrを返してみましょう。次は練習問題でResultを使った問題に挑戦します。