if 表達式
在Rust中, if語句的判斷條件不需要用( )
括起來, 它會認為所有在if
和 {
之間的表達式就是判斷條件,例如:
if num == 5 {msg = "five";
}
判斷條件的表達式必須返回一個bool
型的值, 因為Rust是一個不喜歡進行強制類型轉換的語言,絕大多數時候, Rust都不會對數據進行強制類型轉換,也就是說,下面的例子是一個錯誤的范例:
if 1 {msg = "five"
}
如果要進行多分支的條件判斷,可以使用else if
(注意 else
和if
是分開的),最后也可以用else
結尾, 例如:
if num == 5{msg = "five";
} else if num == 4 {msg = "four";
} else {msg = "other";
}
注意, if
是一種表達式, 而不是語句。 語句不會返回值, 而表達式會返回值, 因此,上面的代碼可以改寫成這樣:
msg = if num == 5{"five"
} else if num == 4 {"four"
} else {"other"
}; // 注意, 這是一個賦值語句, 語句應以 ; 結尾
注意,在上面的例子中,每個判斷分支的結尾沒有;
, 因為這是一個尾部表達式, 用于給if表達式返回一個值;我們也不能使用return
關鍵字, 而只能使用尾部表達式,因為return
只能用于函數定義的代碼塊中,給函數返回結果;另外,每個判斷分支返回的值的數據類型必須相同, 否則Rust編譯器無法確定變量msg
的數據類型; 在if表達式的最后有一個;
, 因為整體來看, 這是一個賦值語句, 把if表達式的返回值賦值給了變量msg
, 而Rust的語句應該以;
結尾。
三元表達式?
Rust中沒有三元表達式的設計, 例如在C語言中, 三元表達式形如:
num = a ? b : c;
雖然這種寫法確實簡單快捷, 但是即便這種簡單的例子,其實也并不是特別易讀和一目了然。如果事情稍微變得復雜一些, 加上一些三元表達式的嵌套, 看起來就更加的令人困惑了,比如:
num = a ? x ? y : z : c;
在Rust中我們選擇拋棄三元表達式, 因為用if就已經能夠簡單的表達需求了, 比如:
num = if a {b} else {c};
即使存在一些嵌套也是比較簡單易讀的,
num = if a {if x {y} else {z}
} else {c
}
loop 循環
loop
是無條件的循環, 與變量不可變
的原因類似, Rust的這個設計的初衷, 也是考慮到編譯器如果確定一個循環式無條件執行的情況下, 可以做更多的優化,從而獲得更好的性能。
當然, 正如變量也需要改變,循環最終仍然是需要終結的。在Rust中,我們也使用break
語句來跳出循環,例如:
loop {break;
}
但是如何跳出多層循環呢,比如:
loop {loop {loop {break;}}
}
默認情況下, 這只會跳出最內層的循環,如果我想跳出指定層級的循環應該怎么辦呢?Rust允許我們給循環打標簽,以便滿足我們提到的這種需求, 標簽的格式是'標簽名
(以一個'
開頭), 下面的例子展示了如何從讓break語句跳出指定的循環:
'bob: loop {loop {loop {break 'bob;}}
}
最外層的循環被打上了一個名為'bob
的標簽, 而break 'bob
語句告訴我們, 要跳出的正是這個'bob
循環。與break
的用法類型,continue
語句通常用于跳過本次循環,進入到下一次循環, continue
同樣可以指定一個標簽, 告訴代碼下一次循環的入口在哪里, 例如:
'bob: loop {loop {continue 'bob;}
}
while 循環
while
循環的行為和loop
基本一致, 只是每次進行循環前, 都會進行條件判斷, 當條件判斷表達式的返回值為true
時, 才會繼續進行下一輪循環。 與if表達式的條件判斷一樣, 條件判斷表達式的返回值必須為bool
型, Rust不會為其他類型的返回值進行強制類型轉換。格式如下:
while dizzy() {do_stuff()
}
用loop加上if, 也可以很容易的改寫while表達式:
loop {if !dizzy() {break}do_stuff()
}
不要覺得這樣做是不是因為我太無聊了,Rust中并沒有do while
的設計, 用上面的改寫方法, 就可以輕松的實現do while
的效果了:
loop {do_stuff()if !dizzy() {break}
}
for 循環
和大多數現代編程語言一樣, Rust中的for
循環會遍歷一個可迭代對象中的每個值。復合數據類型和集合數據類型(collections)通常都會有一些方法來返回一個可迭代對象,用于for
循環使用。
for num in [7, 8, 9].iter(){// do stuff with num
}
上面的例子中[7, 8, 9]這個數組調用了iter()
函數來獲取了一個迭代器,iter()
這個函數也是通用的獲取迭代器的方法。一些有序的數據類型的迭代器會有序的返回一組值, 但一些無序的數據類型的迭代器返回的值的順序就是隨機的了。
Rust的for循環中, 如果迭代器返回的是一組值, 那么for循環中也可以用一組變量來直接解構并接收返回的值,例如:
let a = [(1, 2), (3, 4)];
for (x, y) in a.iter() {// do stuff with x, y
}
還有一個常見的場景是在某個數字范圍內進行for循環, 指定數字范圍的格式是起始(閉)..結束(開)
:
for num in 0..50 {// do stuff with num 1 to 49
}
如果想要包含結束的數字, 那么可以用這種格式起始(閉)..=結束(閉)
for num in 0..=50 {// do stuff with num 1 to 50
}
小結
本章介紹了if條件判斷語句, 和幾種循環語句的格式和使用場景, 下一章將介紹Rust中比較重要的一種數據類型,String。