RustのOption型を理解する

RustのOption型を理解する

Option型、Optional型を持つプログラミング言語はいくつもあります。ここでは、RustのOption型の使い方について説明します。

目次

Option型とは

Option型は、値が存在する場合と存在しない場合を表現できる列挙型です。標準ライブラリでは、以下のように定義されています。

pub enum Option<T> {
    None,
    Some(T),
}

なぜOption型を使用するのか

Rustでは、nullundefinedのような値が存在しないため、値の有無を示すためにOption型が使用されます。これにより、コンパイル時に値の有無を考慮しなければならないことが明示され、ヌルポインタ例外のようなランタイムエラーを防ぐことができます。

Option型の使い方

具体的な使用例で、使用方法を確認していきましょう。

Option型を定義する

Option型を定義する場合は、型をOption<T>型にし、値はSomeまたはNoneを使います。

    // Option<i32>型の変数を定義する
    // 値が存在する場合はSomeに値を渡して代入する
    let val: Option<i32> = Some(100);
    //  値が存在しない場合はNoneを代入する
    let none: Option<i32> = None;

値が存在しているときだけ取り出し、存在しないときはデフォルト値を使う

値が存在するときだけその値を取り出し、値が存在しないときはデフォルト値を使う場合はmatch式を使うとよいでしょう。

// 偶数の時だけ2倍の値を返す
fn get_double_value_when_even(num: i32) -> Option<i32> {
    return if (num % 2) == 0 {
        Some(num * 2)
    } else {
        None
    }
}

fn main() {
    let value = match get_double_value_when_even(10) {
        None => 0,
        Some(v) => v,
    };
    println!("value is {}", value);
}

この例では、値が存在する場合はその値を変数に代入し、存在しない場合はデフォルト値の0を変数に代入しています。

単純に値を取り出したいだけであれば、unwrap_or関数を使うことで、もっと簡単に書くことができます。

// 偶数の時だけ2倍の値を返す
fn get_double_value_when_even(num: i32) -> Option<i32> {
    return if (num % 2) == 0 {
        Some(num * 2)
    } else {
        None
    }
}

fn main() {
    let value = get_double_value_when_even(10).unwrap_or(0);
    println!("value is {}", value);
}

値が存在しているか存在しないかで処理を分岐する

値が存在する時はその値を使って処理を行い、値が存在しなときはそれとは別の処理を行う場合はif文を使うとよいでしょう。

// 偶数の時だけ2倍の値を返す
fn get_double_value_when_even(num: i32) -> Option<i32> {
    return if (num % 2) == 0 {
        Some(num * 2)
    } else {
        None
    }
}

fn main() {
    if let Some(value) = get_double_value_when_even(10) {
        println!("result: {}", value);
    } else {
        println!("値は存在しません");
    }
}

この例では、値が存在するときはその値を表示し、値が存在しないときは存在しない旨のメッセージを表示しています。

値が存在している/していないを判定する

値自体が必要なわけではなく、値が存在している/していないだけが必要な状況ということがあります。このような場合はis_some関数やis_none関数を使用するとよいでしょう。

struct Person {
    pub name: String,
    pub age: u32,
}

impl Person {
    /// Personテーブルをidで検索する
    fn findById(id: &str) -> Option<Person> {
        if id == "user01" {
            Some(Person {
                name: String::from("John"),
                age: 20,
            })
        } else {
            None
        }
    }
}

fn main() {
    if Person::findById("user01").is_some() {
        // ID"user01"のPersonが存在する場合
        println!("Personは存在します");
    }
}

この例では、値が存在するかどうかをis_some関数で判定しています。値が存在しない場合を判定したい場合はis_none関数を使います。

まとめ

RustのOption型は、コードの安全性と明確さを向上させるための強力なツールです。値が存在するかどうかを常に考慮することで、予期しないエラーのリスクを減少させます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次