<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          match 是什么語法?PHP8 也加了

          共 7096字,需瀏覽 15分鐘

           ·

          2021-06-11 13:55

          閱讀本文大概需要 5 分鐘。

          大家好,我是站長 polarisxu。

          這是 Rust 勸退系列的第 8 個教程,探討 Rust 中的模式匹配。

          01 match 表達(dá)式

          關(guān)于 match 表達(dá)式,很多其他語言并沒有,比如 Go 語言。不過有些語言開始支持 match,比如 PHP 8.0 就有了 match 表達(dá)式。

          一般地可以認(rèn)為 match 和 switch 類似,所以 Rust 中沒有 switch。

          match 用于檢查某個當(dāng)前的值是否匹配一組/列值中的某一個??匆粋€具體的例子:

          fn test_match(number: i32) -> &'static str {
              match number {
                  // 匹配單個值
                  1 => {println!("One!"); "One!"},
                  // 匹配多個值
                  2 | 3 | 5 | 7 | 11 => "This is a prime",
                  // 匹配一個閉區(qū)間范圍
                  13..=19 => "A teen",
                  // 處理其他情況
                  _ => "Ain't special",
              }
          }

          看起來是一個簡單的語法結(jié)構(gòu),但大概率在其他語言沒見過。簡單解釋下:

          • 跟其他語言的 switch 類似,可以匹配多個分支;多個分支之間,使用 , 分隔;
          • 在 match 分支中,=> 左側(cè)是模式,因此叫做模式匹配,比如 | 表示匹配多個值;..= 表示匹配一個范圍;右側(cè)是在左側(cè)匹配成功時要執(zhí)行的操作;
          • match 要求窮盡,也就是要包含所有可能的值。因此提供了 _,用來處理所有其他情況,類似 switch 的 default 分支;但只要窮盡了,可以沒有 _;
          • 如果右側(cè)操作是多個語句,需要放在 {} 中;
          • match 是表達(dá)式,它的結(jié)果是匹配到的模式中,執(zhí)行操作的最后一個表達(dá)式的結(jié)果。這在 Rust 中是很常見的,之前提到過,Rust 中一切皆表達(dá)式。所以,這個例子中 match 表達(dá)式的值即為函數(shù)的返回值。因此,match 的所有分支必須返回同一數(shù)據(jù)類型;
          • 注意 match 表達(dá)式最后是否有分號的區(qū)別;

          日常吐槽:在 match 中匹配區(qū)間,如果想和 for in 一樣,使用 .. 來表示半閉半開區(qū)間,結(jié)果報錯??吹劫Y料說應(yīng)該使用 ,但卻提示該語法已廢棄!為啥語法結(jié)構(gòu)還不保持一致呢?!

          看一個接收 match 結(jié)果的例子:

          let boolean = true;
          let binary = match boolean {
            false => 0,
            true => 1,
          }; // 注意這里的分號
          println!("{} -> {}", boolean, binary);

          02 match 其他用法

          上面介紹了常規(guī)的 match 操作。match 還有很多其他的用法。

          解構(gòu)

          當(dāng)元組和 match 一起時,可以解構(gòu)元組。

          fn main() {
            // 試一試將不同的值賦給 `pair`
              let pair = (0, -2);
              
              println!("Tell me about {:?}", pair);
              // match 可以解構(gòu)一個元組
              match pair {
                  // 解構(gòu)出第二個值
                  (0, y) => println!("First is `0` and `y` is `{:?}`", y),
                  (x, 0) => println!("`x` is `{:?}` and last is `0`", x),
                  _      => println!("It doesn't matter what they are"),
                  // `_` 表示不將值綁定到變量
              }
          }

          關(guān)于枚舉和指針、引用和 match 的結(jié)合,以后遇到再講解。

          guard 語句

          在 match 分支中可以加上過濾條件。接著上面元組解構(gòu)的例子:

          fn main() {
              let pair = (2, -2);

              println!("Tell me about {:?}", pair);
              match pair {
                  (x, y) if x == y => println!("These are twins"),
                  // `if` 條件部分是一個衛(wèi)語句
                  (x, y) if x + y == 0 => println!("Antimatter, kaboom!"),
                  (x, _) if x % 2 == 1 => println!("The first one is odd"),
                  _ => println!("No correlation..."),
              }
          }

          綁定

          這是什么意思呢?看一個例子:(來自 rust by example)

          // `age` 函數(shù),返回一個 `u32` 值。
          fn age() -> u32 {
              15
          }

          fn main() {
              println!("Tell me type of person you are");

              match age() {
                  0             => println!("I'm not born yet I guess"),
                  // 可以直接 `match` 1 ..= 12,但怎么把歲數(shù)打印出來呢?
                  // 在 1 ..= 12 分支中綁定匹配值到 `n` ?,F(xiàn)在年齡就可以讀取了。
                  n @ 1  ..= 12 => println!("I'm a child of age {:?}", n),
                  n @ 13 ..= 19 => println!("I'm a teen of age {:?}", n),
                  // 不符合上面的范圍。返回結(jié)果。
                  n             => println!("I'm an old person of age {:?}", n),
              }
          }

          match 后是一個函數(shù),我們希望在分支中,根據(jù)匹配結(jié)果,使用 age 函數(shù)的返回值。當(dāng)然,這個例子有點多此一舉,完全可以在 match 之前用變量存儲 age 函數(shù)的返回值。

          那換一個例子:

          fn some_number() -> Option<u32> {
              Some(41)
          }

          fn main() {
              match some_number() {
                  Some(n @ 40..=42) => println!("The Answer: {}!", n),
                  Some(n)      => println!("Not interesting... {}", n),
                  _            => (),
              }
          }
          • 關(guān)于 Option 以后講解

          這個例子很好的講解了綁定的作用:分支中想要使用匹配的結(jié)果,通過 @ 符號可以將匹配的結(jié)果和某個變量綁定,然后就可以使用這個變量了。

          03 if let 和 while let

          這兩個結(jié)構(gòu)其他語言沒見過,可以理解為是某些場景下替代 match,讓代碼更簡潔,因為 match 必須窮盡所有情況,而 if let 和 while let 沒有此限制。

          以下代碼:

          let some_u8_value = Some(3u8);
          match some_u8_value {
            Some(3) => println!("three"),
            _ => (), // 有點多余
          }

          改為 if let:

          let some_u8_value = Some(3u8);
          if let Some(3) = some_u8_value {
           println!("three");
          }
          • 和 match 一樣,if let 和 while let 都是表達(dá)式;
          • if/while let 等號左側(cè)是模式,右側(cè)是要匹配的值;所以當(dāng)右側(cè)的值和左側(cè)的模式匹配時,執(zhí)行對應(yīng)的語句塊;所以,有時候 if let 也可以單純的當(dāng)做解構(gòu)使用;
          • if let 支持普通的 else if 和 else;while let 沒有 else;

          while let 語法和 if let 類似。這里就不舉例子了。

          04 小結(jié)

          Rust 中的 match 雖然和其他語言的 switch 類似,很顯然,match 的復(fù)雜度比 switch 高。當(dāng)然,不管復(fù)雜與否,最關(guān)鍵還是要實際使用,需要不斷實際練習(xí)。

          通常,match 和 Option、枚舉一起使用,因此,在講解這兩個知識點時,一般會使用到 match。




          往期推薦


          我是 polarisxu,北大碩士畢業(yè),曾在 360 等知名互聯(lián)網(wǎng)公司工作,10多年技術(shù)研發(fā)與架構(gòu)經(jīng)驗!2012 年接觸 Go 語言并創(chuàng)建了 Go 語言中文網(wǎng)!著有《Go語言編程之旅》、開源圖書《Go語言標(biāo)準(zhǔn)庫》等。


          堅持輸出技術(shù)(包括 Go、Rust 等技術(shù))、職場心得和創(chuàng)業(yè)感悟!歡迎關(guān)注「polarisxu」一起成長!也歡迎加我微信好友交流:gopherstudio


          瀏覽 38
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产精品自在拍在线拍 | 国产精品911 | 久久国产乱子伦免费精品 | 欧美成人午夜 | 黄色草逼视频 |