rust流程控制的具體使用
一、分支
(一)if
1.if
語法格式
if boolean_expression { }
例子
fn main(){ let num:i32 = 5; if num > 0 { println!("正數(shù)"); } }
條件表達(dá)式不需要用小括號。
條件表達(dá)式必須是bool類型。
2.if else
語法格式
if boolean_expression { } else { }
例子
fn main() { let num = 12; if num % 2==0 { println!("偶數(shù)"); } else { println!("奇數(shù)"); } }
if else既可以作語句,又可以作表達(dá)式。當(dāng)作表達(dá)式時,它的值是其分支代碼塊最后一個表達(dá)式的值。
我們可以在 let 語句的右側(cè)使用它,例如:
fn main() { let condition = true; let number = if condition { 5 } else { 6 }; println!("The value of number is: {number}"); }
值取決于哪個代碼塊被執(zhí)行。這意味著 if 的每個分支的可能的返回值都必須是相同類型;
在上例中,if 分支和 else 分支的結(jié)果都是 i32 整型。如果它們的類型不匹配,如下面這個例子,則會出現(xiàn)一個錯誤:
fn main() { let condition = true; let number = if condition { 5 } else { "six" }; println!("The value of number is: {number}"); }
3.if else if
語法格式
if boolean_expression1 { } else if boolean_expression2 { } else { }
例子
fn main() { let num = 2 ; if num > 0 { println!("{} is positive",num); } else if num < 0 { println!("{} is negative",num); } else { println!("{} is neither positive nor negative",num) ; } }
(二)if let
句法
IfLetExpression : if let Pattern = Expression BlockExpression (else ( BlockExpression | IfExpression | IfLetExpression ) )?
1.if let
語法格式
if let Pattern = Expression { }
Pattern就是模式。
如果Pattern與Expression匹配,就執(zhí)行相應(yīng)的代碼塊。
可以使用操作符 | 指定多個模式。 這與match表達(dá)式中的 | 具有相同的語義
例子
enum E { X(u8), Y(u8), Z(u8), } let v = E::Y(12); if let E::X(n) | E::Y(n) = v { assert_eq!(n, 12); }
2.if let else
語法格式
if let Pattern = Expression { } else { }
例子
let dish = ("Ham", "Eggs"); if let ("Bacon", b) = dish { println!("Bacon is served with {}", b); } else { println!("No bacon will be served"); }
if let else與if else一樣既可以作語句,又可以作表達(dá)式。當(dāng)作表達(dá)式時,它的值是其分支代碼塊最后一個表達(dá)式的值。
fn main() { let x = Some(3); let a = if let Some(1) = x { 1 } else { 5 }; println!("{a}"); }
3.if let else if let
語法格式
if let Pattern1 = Expression1 { } else if let Pattern2 = Expression2 { }else { }
4.if和if let混合使用
語法格式
if let Pattern = Expression { } else if boolean_expression{ }else { }
例子
let x = Some(3); let a = if let Some(1) = x { 1 } else if x == Some(2) { 2 } else if let Some(y) = x { y } else { -1 }; assert_eq!(a, 3);
5.if let等價于match
例如:
if let PATS = EXPR { /* body */ } else { /*else */ } 等價于 match EXPR { PATS => { /* body */ }, _ => { /* else */ }, // 如果沒有else塊,這相當(dāng)于 `()` }
在一些場合下,用match并不優(yōu)雅,因為match必須考慮所有可能的值。
比如:
let optional = Some(7); match optional { Some(i) => { println!("This is a really long string and `{:?}`", i); }, _ => {}, // 必須有,因為 `match` 需要覆蓋全部情況。不覺得這行很多余嗎? };
if let在這樣的場合要簡潔得多
fn main() { let number = Some(7); if let Some(i) = number { println!("Matched {:?}!", i); } }
另一個好處是:if let允許匹配枚舉非參數(shù)化的變量,即枚舉未注明 #[derive(PartialEq)],我們也沒有為其實現(xiàn)PartialEq。在這種情況下,通常if Foo::Bar==a會出錯,因為此類枚舉的實例不具有可比性。但是,if let是可行的。
你想挑戰(zhàn)一下嗎?使用if let修復(fù)以下示例:
// 該枚舉故意未注明 `#[derive(PartialEq)]`, // 并且也沒為其實現(xiàn) `PartialEq`。這就是為什么下面比較 `Foo::Bar==a` 會失敗的原因。 enum Foo {Bar} fn main() { let a = Foo::Bar; // 變量匹配Foo::Bar if Foo::Bar == a { // ^-- 這就是編譯時發(fā)現(xiàn)的錯誤。使用 `if let` 來替換它。 println!("a is foobar"); } }
(三)match
match用于檢查值是否匹配一組模式中的某一個。似于C語言中的 switch 語句
語法格式
match variable_expression { pattern1 => { }, pattern2 => { // }, _ => { // 默認(rèn) } };
例子
fn main() { let x = 1; match x { 1 => println!("one"), 2 => println!("two"), 3 => println!("three"), 4 => println!("four"), 5 => println!("five"), _ => println!("something else"), } }
match既可以作語句,也可以作表達(dá)式,作表達(dá)式時,它把匹配分支代碼塊的最后一條表達(dá)式的結(jié)果當(dāng)作返回值。
例子
fn main(){ let state_code = "MH"; let state = match state_code { "MH" => "Maharashtra", "KL" => "Kerala", "KA" => "Karnadaka", "GA" => "Goa", _ => "Unknown" }; println!("State name is {}",state); } 運行結(jié)果 State name is Maharashtra
模式守衛(wèi)
守衛(wèi)出現(xiàn)在模式的后面,由關(guān)鍵字if后面的布爾類型表達(dá)式組成。
當(dāng)模式匹配成功時,將執(zhí)行守衛(wèi)表達(dá)式。 只有此表達(dá)式的計算結(jié)果為真,才認(rèn)為完全匹配成功。 否則,匹配將測試下一個模式,包括測試同一分支中運算符 | 分割的后續(xù)模式。
fn main() { let maybe_digit = Some(8); match maybe_digit { Some(x) if x < 10 => println!("digit < 10"), Some(x) => println!("digit >= 10"), None => panic!(), }; }
注意:使用操作符 | 的分支可能會導(dǎo)致后跟的守衛(wèi)必須多次執(zhí)行的副作用。 例如:
use std::cell::Cell; let i = Cell::new(0i32); match 1 { 1 | _ if { i.set(i.get() + 1); false } => {} _ => {} } assert_eq!(i.get(), 2);
二、循環(huán)
(一)for
Rust 中的 for 只有 for in 這種格式,常用于遍歷容器的元素
句法
IteratorLoopExpression : for Pattern in Expression BlockExpression
pattern就是模式
例子
下面的代碼,使用 for…in 循環(huán),重復(fù)輸出1到11之間的數(shù)字(不包括11)
fn main(){ for x in 1..11{ println!("x is {}",x); } }
fn main() { let a = [10, 20, 30, 40, 50]; for element in a { println!("the value is: {element}"); } }
(二)while
句法
PredicateLoopExpression : while Expression BlockExpression
例子
下面的代碼,使用 while 循環(huán)重寫下上面的代碼,重復(fù)輸出1到11之間的數(shù)字(不包括11)
fn main(){ let mut x = 1; while x < 11{ println!("inside loop x value is {}",x); x+=1; } println!("outside loop x value is {}",x); }
(三)loop
loop 語句代表著一種死循環(huán)。
語法格式
loop { }
范例
下面的語句,我們使用 loop 輸出1到無限大的數(shù)字。
fn main(){ let mut x = 0; loop { x+=1; println!("x={}",x); } }
(四)while let
句法
PredicatePatternLoopExpression : while let Pattern = Expression BlockExpression
Pattern就是模式
如果值與模式匹配,則執(zhí)行循環(huán)體塊。如果不匹配,則跳出循環(huán)。
可以使用操作符 | 指定多個模式。
let mut vals = vec![2, 3, 1, 2, 2]; while let Some(v @ 1) | Some(v @ 2) = vals.pop() { // 打印2, 2, 然后1 println!("{}", v); }
例子
let mut x = vec![1, 2, 3]; while let Some(y) = x.pop() { println!("y = {}", y); } while let _ = 5 { println!("不可反駁模式總是會匹配成功"); break; }
while let等價于包含match的loop。
如下:
while let PATS = EXPR { /* loop body */ } 等價于 loop { match EXPR { PATS => { /* loop body */ }, _ => break, } }
三、循環(huán)標(biāo)簽
句法
LoopLabel : LIFETIME_OR_LABEL :
一個循環(huán)表達(dá)式可以選擇設(shè)置一個標(biāo)簽。這類標(biāo)簽被標(biāo)記為循環(huán)表達(dá)式之前的生存期(標(biāo)簽),如 'foo: loop { break 'foo; }、'bar: while false {}、'humbug: for _ in 0…0 {}。 如果循環(huán)存在標(biāo)簽,則嵌套在該循環(huán)中的帶此標(biāo)簽的break表達(dá)式和continue表達(dá)式可以退出此標(biāo)簽標(biāo)記的循環(huán)層或?qū)⒖刂屏鞣祷刂链藰?biāo)簽標(biāo)記的循環(huán)層的頭部。
四、跳出循環(huán)
(一)break
句法
BreakExpression : break LIFETIME_OR_LABEL? Expression?
當(dāng)遇到break時,相關(guān)的循環(huán)體的執(zhí)行將立即結(jié)束,例如:
let mut last = 0; for x in 1..100 { if x > 12 { break; } last = x; } assert_eq!(last, 12);
break表達(dá)式只能跳出一層循環(huán),如果要跳出多層循環(huán),就要使用循環(huán)標(biāo)簽。
例如:
'outer: loop { while true { break 'outer; } }
break表達(dá)式只允許在循環(huán)體內(nèi)使用,它有break、break 'label、break EXPR、break 'label EXPR這四種形式。
fn main(){ let mut x = 0; loop { x+=1; if x > 10 { break; } println!("x={}",x); } }
break 可以返回值
當(dāng)使用loop循環(huán)時,可以使用break表達(dá)式從循環(huán)中返回一個值,通過形如break EXPR或break 'label EXPR來返回,其中EXPR是一個表達(dá)式。
其后不跟表達(dá)式的break與后跟 () 的break效果相同。
例如:
let (mut a, mut b) = (1, 1); let result = loop { if b > 10 { break b; } let c = a + b; a = b; b = c; }; // 斐波那契數(shù)列中第一個大于10的值: assert_eq!(result, 13);
(二)continue
句法
ContinueExpression : continue LIFETIME_OR_LABEL?
當(dāng)遇到continue時,相關(guān)的循環(huán)體的當(dāng)前迭代將立即結(jié)束,并將控制流返回到循環(huán)頭。 在while循環(huán)的情況下,循環(huán)頭是控制循環(huán)的條件表達(dá)式。 在for循環(huán)的情況下,循環(huán)頭是控制循環(huán)的調(diào)用表達(dá)式。
與break一樣,continue只能跳過一層循環(huán),如果要跳過多層,可以使用continue 'label。
continue表達(dá)式只允許在循環(huán)體內(nèi)部使用。
fn main(){ for x in 1..11{ if 5 == x { continue; } println!("x is {}",x); } }
到此這篇關(guān)于rust流程控制的具體使用的文章就介紹到這了,更多相關(guān)rust流程控制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Rust編程中的共享狀態(tài)并發(fā)執(zhí)行
雖然消息傳遞是一個很好的處理并發(fā)的方式,但并不是唯一一個,另一種方式是讓多個線程擁有相同的共享數(shù)據(jù),本文給大家介紹Rust編程中的共享狀態(tài)并發(fā)執(zhí)行,感興趣的朋友一起看看吧2023-11-11