理所當然地,Rust提供了條件、循環等控制流程。由於enum的特殊點(可以承載數據),Rust的條件結構爲其有專門的設計,所以也在此簡單介紹enum。
但壽元、所有權、引用借用等概念也影響enum的實際使用,故而會在Rust學習筆記/再敘enum和模式匹配再次討論。
條件結構
if
表達式
if
後接一個 bool
類型的表達式(不需要括號),且 if
和 else
子句(均爲表達式)均需要大括號。特殊地,如要書寫 else-if ,則 else if
合併爲一個表達式。
... let m = if a < 5 { println!("a小於5"); 4 } else if a < 8 { println!("a小於8"); 7 } else { 10 } println!("m={}", m);
注意 if
各子句(表達式)的返回值應當是相同的類型,否則會造成編譯錯誤(類型錯誤)。
另外, if
表達式還支持與enum聯合使用的模式匹配,使用 if let
語法,見下文enum部分。
模式匹配(match
)
Rust的 match
基本就是其他語言中的 switch
,但和其他語言相比多了對條件的完備性檢查:必須匹配所有的可能性。另外,類似於 if
,match
也是表達式。
let x = 5; let number = match x { 1 => "one", 2 => "two", 3 => "three", 4 => "four", 5 => "five", _ => "anything else", };
上面代碼展示了match的基本語法,其中_
代表「任何」(也就是其他語言中的default
)。
理論上來說,同一枝匹配的「模式」也可以是多值,比如如下的例子:
match x { 1 | 2 => "one or two", 3 ..= 9 => "three to nine", _ => "anything else", };
注意這裏的範圍是用「範圍模式」而非「 範圍表達式」寫就的。官方文檔的內容預示着還有更高級的形式,有興趣的可以去翻閱文檔。
當涉及enum後,match
則起到更大的作用(見下文)。
循環結構
Rust支持三種循環結構 loop
、while
和 for
。
for
for
就是 for each
。同Python中的寫法類似,Rust中也需要 for ... in ...
。
fn main() { let a = [10, 20, 30, 40, 50]; for element in a.iter() { println!("the value is: {}", element); } }
fn main() { for number in (1..4).rev() { println!("{}!", number); } println!("LIFTOFF!!!"); }
同樣來自 官方教程控制流程一節 。
enum
Rust的enum可以簡單承載數據,這使得它承擔了一些很有意義的其他功能。
比如說,Rust中沒有null
(不是改名這種文字遊戲),取而代之的則是一個叫做Option<T>
的enum,其有效取值分別是Some(T)
和None
(和你想得一樣,這裏的<T>
是泛型參數,而(T)
則是我們說到的數據承載)。由於泛型和強類型兩項特性,這一設定帶來兩個結論:
None
不能越過類型邊界Some(T)
和None
必須分別處理,否則編譯無法通過
於是,對Java等語言中普遍存在的空指針問題,Rust程序員完全不需要擔心:編譯時就需要確認數據是否存在,運行時一定不會出現空指針。
特殊設計的 if let
等結構便是配合這類機制的良方,方便寫出簡短的代碼:
let some_value = Some(3); if let None = some_value { println!("some_value is None") } if let Some(x) = some_value { println!("{}", x); } let some_value2 = Some("test"); match some_value2 { Some(s) => println!("{}", s), None => println!("None!"), }
可以看到,這裏的控制流程的判定條件是該賦值是否成功,並且變量x
被自動解包賦值(3
,而非Some(3)
)。
另外,這裏的match
並沒有使用_
,因爲Rust編譯器知道some_value2
是一個Option
類型(更具體的,Option<&'static str>
類型)的值,其可能取值只有兩種。
您可以在Hypothesis上的該群組內進行評論,或使用下面的Disqus評論。