Rustのmatch演算の書き方【制御フロー演算子、分岐処理】
目次
- Rustのmatch演算を使ってみる
- match演算子の構造
- 基本的なmatch演算
- ブレースで複数行、計算する
- match演算の結果を受け取る
- 文字列(&str)とマッチング
- 文字列(String)とマッチング
- enumとのマッチング
- Optionをmatchで処理する
- Resultをmatchで処理する
- おわりに
Rustのmatch演算を使ってみる
今回はRustのmatch演算子について解説します。
Rustでは条件分岐にif, それからmatchが使えます。
matchを使うと他言語で言うところのswitch文みたいな処理が書けます。
またRustのmatchはエラーハンドリングでもよく使われる演算子なので覚えておきたいところです。
それでは解説していきます。
match演算子の構造
まずmatch演算子の構造です。
match演算子の構造は↓のようになっています。
match 条件に使う値 { マッチさせたい値1 => 実行する式, マッチさせたい値2 => 実行する式, _ => 実行する式, }
条件に使う値に対してマッチさせたい値を書き、それに=>
を付けて右側にマッチした場合の式を書きます。
またマッチさせたい値にどれもマッチしなかった場合は_
のところが実行されます。
match演算子は文ではなく演算子なので当然、演算結果を返します。
この辺が他言語とは違うところなので注意が必要です。
基本的なmatch演算
では基本的なmatch演算について見てみます。
整数を使った場合です。
let n: i32 = 2; match n { 0 => println!("zero"), 1 => println!("one"), 2 => println!("two"), _ => println!("other"), }; // two
上の場合、条件に使う値は変数n
です。
変数n
には整数2
が入っています。
ですので2 => ...
の部分にマッチして「two
」と出力されます。
n
の値を変えてみると他のところにマッチしてくのがわかります。
ブレースで複数行、計算する
match演算でマッチした場合に実行する式は複数書くことができます。
その場合は=>
の右側をブレース({}
)で囲みます。
let n: i32 = 1; match n { 0 => println!("zero"), 1 => { println!("one"); println!("you are no.1!"); println!("i'm excellent!"); }, _ => println!("other"), }; // one // you are no.1! // i'm excellent!
match演算で条件にマッチさせて具体的な処理を書きたい場合はこのようにブレースを使うことが多いと思います。
ただしブレースの中に文や式を書きすぎるとmatch演算が長くなってしまうので注意が必要です。
ほどほどにしてリファクタリングしてください。
match演算の結果を受け取る
match演算は演算子なので結果を返すことができます。
↓のケースはマッチした場合に大きな整数を返すようにしています。
let n: i32 = 2; let result = match n { 1 => 100, 2 => 200, _ => 300, }; println!("result {}", result); // result 200
変数result
には↑の場合は200
が代入されます。
文字列(&str)とマッチング
match演算は文字列とマッチングさせることもできます。
&str
の文字列とマッチさせてみます。
let s: &str = "go to heaven"; match s { "go to hell" => println!("this is hell..."), "go to heaven" => println!("this is heaven!"), _ => println!("other"), } // this is heaven!
Rustでは"hello"
と書いた場合はこれは&str
と判断されます。
ですので↑のように文字列変数に対してダブルクオーテーションで囲った文字列をべた書きすることができます。
文字列(String)とマッチング
String
とマッチさせたい場合はas_str()
を使います。
let s = String::from("go to heaven"); match s.as_str() { "go to hell" => println!("this is hell..."), "go to heaven" => println!("this is heaven!"), _ => println!("other"), } // this is heaven!
as_str()
はString
から&str
を取得します。
match演算の条件式にこれを指定することで分岐のマッチさせたい文字列にマッチさせることができます。
enumとのマッチング
match演算はenum定数ともマッチングさせることができます。
enum Number { One, Two, Three, }; let n = Number::Two; match n { Number::One => println!("one"), Number::Two => println!("two"), Number::Three => println!("three"), } // two
enumの場合は_
が省略されていることに注意してください。
別に省略しなくてもいいんですが、enumに列挙されている定数を網羅的にmatch演算に書いておけば、警告などが出力されることはありません。
match演算は網羅的につまり包括的に値を処理します。
ですのでi32
などを条件にした場合は_
を省略すると怒られてしまいます。
Optionをmatchで処理する
Option
をmatch演算で処理することもできます。
fn get_user_age(user_id: i32) -> Option<usize> { match user_id { 0 => Some(20), 1 => Some(30), _ => None, } } match get_user_age(1) { None => println!("not found"), Some(20) => println!("20 age"), Some(30) => println!("30 age"), Some(_) => println!("other"), }
get_user_age()
はユーザーのIDから年齢を取得するという関数です。
ユーザーIDからユーザーが見つからない場合はNone
を返します。
結果を受け取った側のmatch文はなにやら見慣れない感じです。
しかしそうなんですRustではこのような書き方が可能なわけです。
(^ _ ^) | やるじゃんRust |
(・ v ・) | 調教されよう |
Resultをmatchで処理する
Result
もmatch演算で処理できます。
fn get_user_weight(user_id: i32) -> Result<i32, &'static str> { match user_id { 0 => Ok(60), 1 => Ok(70), _ => Err("not found user"), } } match get_user_weight(1) { Ok(weight) => println!("user weight is {}", weight), Err(err) => println!("{}", err), }
get_user_weight()
はユーザーのIDからユーザーの体重を取得する関数です。
ユーザーが存在すればErr("not found user")
を返します。
呼び出し側のmatch演算ではOk
やErr
を使って分岐を書くことができます。
関数の処理に成功したらOk
のところに行ってエラーになったらErr
のところに行きます。
おわりに
今回はRustのmatch演算子について解説しました。
match演算は大変便利な機能です。
覚えて使えるようになっておきましょう。
(^ _ ^) | マッチマッチマッチです |
(・ v ・) | 踊れmatch演算子 |