RustのMatch
matchは他の言語で言うswitchみたいなもん
ただしmatchを使うときはその値(型)であり得ることを100%網羅する必要がある
code:match.rs
fn main() {
let a = 10;
match a {
0 => println!("aは0"),
1 => println!("aは1"),
// 上記以外の数値だったら下の結果として処理される。変数名を指定してあげると処理で変数が入れられる
n => println!("aは0や1ではない: {}", n),
}
// Result: aは0や1ではない: 10
}
複数の値を同じ処理にする
|を使うことで複数の値を同じ処理にすることができる
code:match_multi.rs
fn main() {
let x = 12;
match x {
11 | 12 => println!("11か12"),
_ => println!("{}", x)
}
}
..=を使うと広い範囲で同じ処理にすることができる
(以前は...という構文だったが、自分が使っているRust v1.49.0は廃止警告が出ていた)
code:match_widerange.rs
fn main() {
let x = 12;
match x {
11 ..= 20 => println!("10から20"),
_ => println!("10から20ではない")
}
}
所有権とmatch
matchは所有権を持っていってしまう
code:match_moved_ownership.rs
fn main() {
let username = Some(String::from("Owner"));
match username {
// 変数usernameの所有権が移動してしまう
Some(name) => println!("Hi {}!", name),
None => ()
}
// 変数usernameの所有権が移動してしまったため、ここでエラー
println!("Welcome back {:?}", username);
}
matchで借用として取り扱うにはrefをつかう
code:match_ref.rs
fn main() {
let username = Some(String::from("Owner"));
match username {
// 借用として取り扱うので所有権がなくならない
Some(ref name) => println!("Hi {}!", name),
None => ()
}
// 変数usernameの所有権はなくなっていないため、これも動く
println!("Welcome back {:?}", username);
}
可変借用したい場合はref mutを使う(無論、大元の変数もmutを付けないといけない)
code:match_ref_mut.rs
fn main() {
let mut username = Some(String::from("Owner"));
match username {
Some(ref mut name) => *name = String::from("Administrator"),
None => ()
}
println!("Welcome back {:?}", username);
// Result: Welcome back Some("Administrator")
}
match内でifを書く
matchの値にifをつけることができる
Option<T>で取り扱うときに便利
code:match_con.rs
fn main() {
let x: Option<i32> = Some(10);
match x {
Some(x) if x <= 10 => println!("10以下の値: {}", x),
Some(x) => println!("10より大きい値: {}", x),
None => println!("わからない")
}
}
ちなみに複数の値でifを使う場合はその複数の値で一致したときにifで一致するかを行う
code:match_con_multi.rs
fn main() {
let x = 4;
let res = true;
match x {
1 | 2 | 3 if res => println!("xは1~3でresはtrue"),
4 ..= 10 if res => println!("xは4~10でresはtrue"),
_ => println!("どれでもない結果")
}
}
@束縛
@を使うと式の結果を指定した変数名に代入できる
code:match_at.rs
struct User {
id: i32
}
fn main() {
let user1 = User {
id: 1
};
match user1 {
User { id: id_num @ 1 ..= 10 } => {
println!("1~10のIDを持つユーザー: {}", id_num)
},
User { .. } => {
println!("それ以外のユーザー")
}
}
}