Lv777

Lv777

github
twitter
jike
playstation
xiaoyuzhou

控制流

Rust 里的控制流与其他语言没什么差异.

if#

if 的条件不带 (), 条件必须是 bool 类型.

if 是表达式,JS 三元表达式效果直接达成了:

let x = if true { 1 } else { 2 }

循環#

循環控制的 loop 以前沒見過,是無限循環。通過 breakcontinue 控制終止和跳過,Rust 里 break 還能返回值. break,continue 以及循環標籤仨概念在 JS 的 for 里也有,就是 ES6 用習慣了沒怎麼接觸.

標準庫 Rangefor 配合起來感覺有點意思。寫 JS 循環就想過怎麼沒個控制循環次數的簡潔方案,這下滿足了.

match#

match 類似 JS 里的 switch, 有嚴格檢查確保窮盡了所有可能性。與 [[數據類型 #枚舉]] 配合可以匹配提取枚舉成員包含的值.

let value = match some_value {
	Some(i) => i,
	None => 0
}

可以使用通配符 other (還以為 other 是個關鍵字) 或 _其他場景做處理,通配符按常理應該寫在最後一個條件,否則會導致其後寫的條件完全無效.

match some_num {
	1 => call(),
	3 => check(),
	other => println!("{}", other),
	// 也可以用 _ 不獲取剩餘情況的具體值
	// _ => (),
}

if let#

只需處理一種情況的場景,使用 if let 語法更簡潔,但比 match 少了窮盡檢查.

if let Some(value) = some_value {
	println!("{}", value);
}

? 運算符#

類似 JS 中的可選鏈, 可作用於 OptionResult 傳播錯誤或 None 值。只能寫在返回值兼容的函數體內,比如要對 Result 使用 ? 必須返回 Result. 有一點不同是對 Result 可以在函數體任何位置使用,這樣做會提前中斷並返回 Result::Err.

模式匹配#

模式 是 Rust 中用來匹配類型結構的語法。有點像 JS 的解構賦值, 理解起來有點反邏輯思路,但可使用的場景更多,控制流大部分都能用模式匹配.

let 語句可以模式匹配,= 左側的模式匹配右側表達式,match 分支裡的 => 左側模式匹配 match 關鍵字右側表達式,if let 語句 = 左側模式匹配右側表達式.

let (x, y) = (1, 2);

match some_value {
	Some(4) | Some(5) => {},
	Some(x) => {},
	None => {}
}

if let 1..=3 = some_value {
} else if is_true{
} else {
}

// 解構結構體
let User { name: username, age } = user;

這麼看 if let 有點像 if (模式匹配結果) 句型.

可反駁性#

如果表達式存在不能匹配模式的可能,則這個模式是可反駁的,比如 match 裡的分支條件。反之為不可反駁的模式。也可以說窮盡所有可能性的情況下是不可反駁的. letfor 只接受不可反駁模式.

忽略模式中的值#

  1. 使用 _ 忽略單個值,可以在一個模式中重複使用;
  2. 使用 .. 忽略剩餘值,但必須保證被忽略的部分沒有歧義;

匹配守衛#

match 的分支條件後可以用 if 關鍵字添加守衛,即額外的匹配條件.

match some_value {
	Some(1) | Some(2) => {},
	Some(v) if v > 0 => {},
	Some(_) => {},
	_ => {}
}

添加的 if 作用於前面的整個模式,如果同時使用了 | 運算符指定了多個模式,if 前的優先級更高。以後八成會被這個坑到.

match x {
	// 這裡無論 x 是幾都不會匹配
	1 | 2 | 3 if false => {},
	_ => {}
}

如果希望同時獲取變量並匹配模式,可以使用 @ 綁定.

match user {
	// 這裡的 age 被用來匹配了, 後面的塊中無法訪問 age 值
	User { age: 1..=18, .. } => {},
	// 這樣就可以用了
	User { age: user_age @ 20..=35, .. } => {}
}
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。