Cover Image for [Rust] OptionやResultと組み合わせて使える?演算子

[Rust] OptionやResultと組み合わせて使える?演算子

概要

Rustの?演算子(question mark operator)がとても便利なのでメモしておく

Option 型に対して使う

例:function get は、Option 型を返すfunction get_opt の戻り値がNoneならそのままNoneを返してSomeなら加工して返却する。

fn get_opt() -> Option<()> {  
    None  
}  
  
fn get() -> Option<()> {  
    let val = get_opt();  
    if val.is_none() {  
        return None;  
    }  
    let unwrapped = val.unwrap();  
    // 何かしらの加工処理  
    Some(unwrapped)  
}

上記のよくある処理を?演算子(question mark operator)を使うとこう書ける

fn get_opt() -> Option<()> {  
    None  
}  
  
fn get() -> Option<()> {  
    let val = get_opt()?;  
    // 何かしらの加工処理  
    Some(val)  
}

めっちゃ楽だし意図がわかりやすい。

Result 型に対して使う

さっきと似たような例。Option部分がResultだったとしても同様な処理になる。 (Error型を定義するのが面倒なのでanyhowを使ってるのは見逃して欲しい)

use anyhow::{anyhow, Result};

fn get_result() -> Result<()> {  
    Err(anyhow!("missing value"))  
}  
  
fn get() -> Result<()> {  
    let val = get_result();  
    if val.is_err() {  
        return Err(anyhow!("some value"));  
    }  
    let unwrapped = val.unwrap();  
    // 何かしらの加工処理  
    Ok(unwrapped)  
}

これも?演算子(question mark operator)を使うことで簡単にできる。

use anyhow::{anyhow, Result};

fn get_result() -> Result<()> {  
    Err(anyhow!("missing value"))  
}  

fn get() -> Result<()> {  
    let val = get_result()?;  
  
    // 何かしらの加工処理  
    Ok(val)  
}

Option 型 と Result 型 の混合パターン

use anyhow::{anyhow, Result};

fn get_opt() -> Option<()> {  
    None  
}  
  
fn get() -> Result<()> {  
    let val = get_opt().ok_or(anyhow!("some value"))?;  
    // 何かしらの加工処理  
    Ok(val)  
}

ok_or と ?演算子(question mark operator)を使うことでかなり簡潔に書ける。 これに気づいてしまって便利すぎると思ってこの記事を書いた。