UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【Rust】matchとは?

Rustにおけるswitch文の書き方を探していたらmatchを使うことがわかった

doc.rust-jp.rs

Java(< 14)やJavaScriptより表現力があるみたい

簡単な使い方は以下

enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter,
}

fn value_in_cents(coin: Coin) -> u32 {
    match coin {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter => 25,
    }
}

{}でブロックを表現できる

fn value_in_cents(coin: Coin) -> u32 {
    match coin {
        Coin::Penny => {
            println!("Lucky penny!");
            1
        },
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter => 25,
    }
}

breakなどは不要

「上記以外すべて」は_を定義する

let some_u8_value = 0u8;
match some_u8_value {
    1 => println!("one"),
    3 => println!("three"),
    5 => println!("five"),
    7 => println!("seven"),
    _ => (),
}

Optionとのマッチ

Rustの場合は基本Nullがないが、明示的にNullの状態をつくりたい場合は、Optionという列挙型にする

Optionは標準ライブラリに定義されている

Option - Rust By Example 日本語版

このOptionに対して、matchを使うと値の有無チェックと値の取得を両方できるので便利

fn plus_one(x: Option<i32>) -> Option<i32> {
    match x {
        None => None,
        Some(i) => Some(i + 1),
    }
}

let five = Some(5);
let six = plus_one(five);
let none = plus_one(None);

Some(T)は型Tのvalueを一つ持ったタプル

NoneはNullに相当するもの

もしNoneに対する処理を書き忘れた場合はコンパイルエラーになるので安全

error[E0004]: non-exhaustive patterns: `None` not covered
(エラー: 包括的でないパターン: `None`がカバーされてません)
 -->
  |
6 |         match x {
  |               ^ pattern `None` not covered

他参考

https://ytyaru.hatenablog.com/entry/2020/08/23/000000