やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

RustでNULLを扱う(Option, Some, None)

 他言語でいうNULLを使いたいときはこれ。

成果物

コード

fn main() {
    let some1 = Some(5);
    let some2 = Some("hello");
    let opt: Option<i32> = None;
    println!("{:?}", some1);
    println!("{:?}", some2);
    println!("{:?}", opt);
    let x: Option<i8> = Some(5);
    println!("{:?}", x);
//    println!("{:?}", 3+x); // error[E0277]: cannot add `std::option::Option<i8>` to `{integer}`
}

Enum std::option::Option

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

 Rustは基本NULLになりえない。もしNULLを使いたいなら明示する必要がある。それが上記のenumOptionである。

 Optionは標準ライブラリに定義されている。さらに初期化処理にもあるため、useなどせずとも使える。列挙子までそうであるため、接頭辞Option::なしでSome, Noneが使える。

 ジェネリック型引数。enum Option<T>は、何かしらの引数を1つだけ持つという意味。

Some(T)

 Some(T)は何かしらの型を1つ持った、匿名タプル構造体型である。

let some1 = Some(5);
let some2 = Some("hello");

 Someの引数はi32型, &str型など、何でもいい。

None

 Noneは他言語でいうところのNULL相当。enumOption<T>の値のひとつであり、引数に構造体をとらない。

let nullable_int: Option<i32> = None;
nullable_int = Some(100);

 変数nullable_intはi32型だが、NULLも許容したい。そんなときにOption<i32>型を使う。

 以下はエラーになる。

nullable_int = 100; // error
nullable_int = Some("hello"); // error
let sum = Some(5) + 1; // error

Some(T)におけるTの値を取得する

fn main() {
    let five = Some(5);
    let six = plus_one(five);
    let none = plus_one(None);
}
fn plus_one(x: Option<i32>) -> Option<i32> {
    match x {
        None => None,
        Some(i) => Some(i + 1),
    }
}

 ポイントはmatch x { Some(i) => ... }Some(i)にあるi。値がなんであれマッチするし、その値を変数iとして取り出せる。

参考

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux

前回まで