🐽

【Rust】呼び出し元でエラーハンドリングをしたい時

2022/11/20に公開

tauriを触っていて、エラーハンドリングをどうしようか悩んでいたところ、いい情報を手に入れました。

Rustで呼び出し元でエラーハンドリングをしたい時

Rustでは ? を利用すると、エラーを呼び出し元へ委譲できます。
使い方としては、Result型を返す関数の呼び出し時に、()の後ろに ? をつけます。
> エラー委譲のショートカット: ?演算子 | The Rust Programming Language に記載されてある通りですね。

▼サンプルコード

fn main() {
    // cause_error関数のエラーハンドリングをmain関数にて行う
    match cause_error_wrapper(12) {
        Ok(val) => println!("{}", val),
        Err(err) => {
            println!("エラーハンドリング");
            println!("{}", err);
        }
    }
}

// エラーが起きるかもしれない関数
fn cause_error(a: i32) -> Result<i32, String> {
    if a <= 10 {
        Ok(a)
    } else {
        Err(String::from("エラー発生"))
    }
}

// cause_errorをラップした関数
fn cause_error_wrapper(a: i32) -> Result<i32, String> {
    println!("いろいろな処理");
    let res = cause_error(a)?; // … (b)
    Ok(res) // … (a)
}

上記のコードでは、cause_error_wrapper関数の中で、エラーが起きるかもしれないcause_error関数の呼び出し時に ? をつけています。
こうすると…、

  • Result型がOkの場合は、値をそのまま取り出して返します。
    (上記のコードでは、resに格納された値をOk()に入れ直して返しています。こうして成功時は、その値を取得できます。…(a))
  • Result型がErrの場合は、cause_error関数から返されたErrが、そのまま関数呼び出し元(main関数)に返されます。…(b)

Rustでは、このようにしてエラーを委譲できます。

注意点として、?はResult型を返す関数の中でしか使用できません。
asyncにおけるawaitみたいな感じですね。

Discussion