在Rust中常常用到模式匹配, match表達式是模式匹配最經常使用的表達式.html
match表達式大體分爲3部分, match關鍵字, head表達式, match塊. 這篇主要討論head表達式怎麼寫.express
咱們知道, Rust中的表達式只有兩種: 位置表達式
, 值表達式
. 相似地, Rust表達式上下文也包括位置表達式上下文
, 值表達式上下文
. head表達式的位置屬於位置表達式上下文, 能夠是位置表達式或值表達式, 且表現出來的行爲不一樣.bash
若是是值表達式, 則會對該表達式求值後, 將結果放到一個臨時位置, 而後按照match分支的順序, 比較是否有符合要求的分支. 第一個匹配到的分支做爲模式匹配的目標分支, 剛剛建立的臨時變量能夠在分支內使用.ui
match 5+3 {
8 => println!("equals!"),
_ => println!("not equals!"),
}
複製代碼
若是head表達式是位置表達式, 則不會分配臨時變量, 而是建立一個綁定, 根據類型是否實現Copy決定是複製語義仍是移動語義.spa
let x = 1;
match x {
1 => println!("one"),
_ => println!("something else"),
}
複製代碼
這裏的x是位置表達式, 所以整段代碼至關於以下這樣:code
let x = 1;
let b = x; // 這裏由於x是i32, 實現了Copy, 所以是複製語義
match b {
1 => println!("one"),
_ => println!("something else"),
}
複製代碼
若是是移動語義, 則會轉移變量的全部權到match表達式, 當match表達式結束後, 變量就被銷燬了.htm
若是不但願轉移全部權, 則可使用ref或ref mut, 聲明一個引用綁定, 按引用進行匹配:get
let x = 1;
match ref x {
&1 => println!("one"),
_ => println!("something else"),
}
複製代碼
這段代碼至關於:string
let x = 1;
let b = &x;
match b {
&1 => println!("one"),
_ => println!("something else"),
}
複製代碼
這裏再提一些我本身理解起來比較困難的點: 當head表達式中匹配的是解引用表達式時, 與匹配引用其實是等價的.io
let y = match *x { 0 => "zero", _ => "some" };
let z = match x { &0 => "zero", _ => "some" };
assert_eq!(y, z);
複製代碼