Flutter/Dart第10天:Dart高級特性Pattern模式的全部類型(共15種)

来源:https://www.cnblogs.com/obullxl/archive/2023/10/05/NTopic2023100501.html
-Advertisement-
Play Games

Pattern模式是Dart 3.0發佈的3個高級特性之一,在第09天我們學習了模式的概覽和用法,對模式的強大之處有了基本的認識,今天我們來看看Dart中的全部模式類型,總共有15種,它們包括邏輯或、邏輯與、關係、值轉換、空檢測、空斷言、常量、變數、標識符、括弧、List列表、Map映射、Recor... ...


Dart官方文檔:https://dart.dev/language/pattern-types

重要說明:本博客基於Dart官網文檔,但並不是簡單的對官網進行翻譯,在覆蓋核心功能情況下,我會根據個人研發經驗,加入自己的一些擴展問題和場景驗證。

和操作符一樣,模式運算也遵循一定的優先順序規則,我們可以通過增加括弧()讓低優先順序規則的模式優先運算:

  1. 邏輯或模式低於邏輯與模式,邏輯與模式低於關係模式:邏輯或 < 邏輯與 < 關係
  2. 一元模式優先順序相同:值轉換、空檢測、空斷言。
  3. 其他的模式都具有最高的優先順序,集合類型(List列表、Map映射和Record記錄)和對象模式包含了其他數據,因此作為外部模式優先運算。

邏輯或模式(Logical-or)

模式語法:子模式1 || 子模式2

模式規則:邏輯或模式通過||分割子模式,從左到右,任何一個子模式匹配則本模式匹配,且後面的子模式不在運算。

子模式可以綁定變數,但是每個子模式綁定的變數必須相同,因為任一子模式匹配則後面的子模式不在運算。

var isPrimary = switch (color) {
    Color.red || Color.yellow || Color.blue => true,
    _ => false
};

邏輯與模式(Logical-and)

模式語法:子模式1 && 子模式2

模式規則:邏輯與模式通過&&分隔子模式,從左到右,任何一個子模式未匹配則本模式未匹配,且後面的子模式不在運算。

子模式可以綁定變數,且每個子模式綁定的變數不能重疊,因為本模式匹配代表每個子模式都必須匹配運算,如果重疊則意味著變數被賦值多次。

switch ((1, 2)) {
  case (var a, var b) && (var c, var d): // ...
}

關係模式(Relational)

模式規則:關係模式通過和給定的常量進行比較完成匹配(比較操作符:==!=<><=>=),true代表匹配成功。通常情況下,關係模式和邏輯與模式配合使用。

String asciiCharType(int char) {
  const space = 32;
  const zero = 48;
  const nine = 57;

  return switch (char) {
    < space => 'control',
    == space => 'space',
    > space && < zero => 'punctuation',
    >= zero && <= nine => 'digit',
    _ => ''
  };
}

值轉換模式(cast)

模式語法:變數 as 類型,如:foo as String

模式規則:值轉換模式允許在對象數據解構過程中進行類型轉換,如果類型無法轉換,則會產生錯誤,建議在類型轉換之前,進行類型斷言。

(num, Object) record = (1, 's');
var (i as int, s as String) = record;

空檢測模式(Null-check)

模式語法:子模式?

模式規則:如果檢測的值不為NULL,則模式匹配。它允許綁定一個變數,變數的類型是該不可為NULL值類型基類。

String? maybeString = 'nullable with base type String';
switch (maybeString) {
  case var s?:
  // 's' has type non-nullable String here.
}

空斷言模式(Null-assert)

模式語法:子模式!

模式規則:首先檢測對象不為NULL,然後檢測對象數據值。如果匹配的值為NULL,則會拋出錯誤。它常用於解構並賦值場景,且保證所賦值非NULL。

List<String?> row = ['user', null];
switch (row) {
  case ['user', var name!]: // ...
  // 'name' is a non-nullable string here.
}

(int?, int?) position = (2, 3);
var (x!, y!) = position;

常量模式(constant)

當值為常量時,常量模式匹配,常量包括:123, null, string, math.pi, SomeClass.constant, const Thing(1, 2), const (1 + 2)等。

switch (number) {
  // Matches if 1 == number.
  case 1: // ...
}

我們可以通過字面常量、命名的常量等方式使用常量模式:

  • 數字字面量:123, 45.56
  • 布爾字面量:true
  • 字元串字面量:string
  • 命名常量:someConstant, math.pi, double.infinity
  • 常量構造器:const Point(0, 0)
  • 常量集合字面量:const [], const {1, 2}

其他更多複雜的常量表達式,可以通過()包裹,並增加const首碼:const (const (1 + 2))

// List or map pattern:
case [a, b]: // ...

// List or map literal:
case const [a, b]: // ...

變數模式(variable)

模式規則:變數模式一般在解構和賦值中,它匹配模式、解構對象並完成賦值,如:var bar, String str, final int _。變數的作用域為模式所在的作用域。如果變數指定了類型,那麼當對象類型和值均匹配時,模式才被匹配。通配符模式是一個特殊的變數模式。

switch ((1, 2)) {
  // 'var a'和'var b'是變數模式,它們值分別為`1`和`2`
  case (var a, var b): // ...
  // 'a'和'b'的作用域在case代碼塊
}

switch ((1, 2)) {
  // `2`是數字類型,與'String b'不匹配,因此本模式為匹配
  case (int a, String b): // ...
}

標識符模式(identifier)

標識符模式與常量模式或變數模式類似:

  • 變數申明上下文:給變數申明一個標識符,如:var (a, b) = (1, 2);
  • 變數賦值上下文:給已經存在的標識符賦值,如:(a, b) = (3, 4);
  • 模式匹配上下文:當作一個命名常量模式(除名字是_外)
  • 任意上下文中的通配符標識符:能匹配任何值且忽略該值,如:case [_, var y, _]: print('The middle element is $y');

括弧模式

模式語法:(子模式)

代碼樣例:如下代碼,和表達式一樣,增加括弧()目的是提高模式的優先順序。

final (x, y, z) = (true, true, false);

// 沒有括弧:true
x || y && z => 'matches true',

// 增加括弧:false
(x || y) && z => 'matches false',

列表模式(List)

模式語法:[子模式1, 子模式2]

List列表模式首先匹配List類型,然後匹配列表元素值,併進行解構和賦值。List列表模式必須匹配整個列表模式元素,我們可以使用...占位符匹配剩餘的列表元素。

// 全列表元素匹配
const a = 'a';
const b = 'b';
switch (obj) {
  case [a, b]:
    print('$a, $b');
}

// 占位符匹配剩餘元素,且忽略
var [a, b, ..., c, d] = [1, 2, 3, 4, 5, 6, 7];
print('$a $b $c $d'); // 1 2 6 7

// 占位符當作一個子列表
var [a, b, ...rest, c, d] = [1, 2, 3, 4, 5, 6, 7];
print('$a $b $rest $c $d'); // 1 2 [3, 4, 5] 6 7

Map映射模式

模式語法:{"key": subpattern1, someConst: subpattern2}

Map映射模式首先匹配Map類型,然後匹配元素內容,併進行解構和賦值。Map映射模式不需要匹配所有元素,忽略未被匹配到的元素。

Record記錄模式

模式語法:(subpattern1, subpattern2)或者(x: subpattern1, y: subpattern2)

Record記錄模式首先匹配記錄,然後解構其欄位。欄位數量、類型和值未匹配,則模式匹配失敗。Record記錄模式必須匹配所有欄位。欄位getter可由變數和標識符模式推導得到。

var (myString: foo, myNumber: bar) = (myString: 'string', myNumber: 1);

// Record pattern with variable subpatterns:
var (untyped: untyped, typed: int typed) = record;
var (:untyped, :int typed) = record;

switch (record) {
  case (untyped: var untyped, typed: int typed): // ...
  case (:var untyped, :int typed): // ...
}

// Record pattern wih null-check and null-assert subpatterns:
switch (record) {
  case (checked: var checked?, asserted: var asserted!): // ...
  case (:var checked?, :var asserted!): // ...
}

// Record pattern wih cast subpattern:
var (untyped: untyped as int, typed: typed as String) = record;
var (:untyped as int, :typed as String) = record;

Object對象模式

模式語法:SomeClass(x: subpattern1, y: subpattern2)

對象模式首先對象類型和屬性類型,並完成對象屬性解構,調用getter方法完成賦值。如果類型不一致,則匹配失敗。對象的屬性名可以忽略,它可以通過變數模式和標識符模式進行推導。和Map映射模式一樣,對象模式不需要匹配所有屬性,忽略未被匹配到的屬性。

switch (shape) {
  // Matches if shape is of type Rect, and then against the properties of Rect.
  case Rect(width: var w, height: var h): // ...
}

// Binds new variables x and y to the values of Point's x and y properties.
var Point(:x, :y) = Point(1, 2);

通配符模式

模式語法:_
_就是通配符模式,它既是變數模式也是標識符模式,但是它無變數也不賦值。它通常作為一個占位符,目的是匹配解構剩下的位置值。通配符如果帶有類型,那麼它僅僅進行類型檢測,而忽略變數和賦值。

// 占位符
var list = [1, 2, 3];
var [_, two, _] = list;

// 類型檢測
switch (record) {
  case (int _, String _):
    print('First field is int and second is String.');
}

我的本博客原地址:https://ntopic.cn/p/2023100501


本文作者:奔跑的蝸牛,轉載請註明原文鏈接:https://ntopic.cn


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • MySQL 是世界上最流行的開源關係型資料庫管理系統之一,而其中的存儲引擎則是其關鍵組成部分之一。InnoDB 存儲引擎在 MySQL 中扮演了重要角色,提供了許多高級功能和性能優化,適用於各種應用程式和工作負載。本文將深入介紹 InnoDB 存儲引擎的各個方面,以幫助您更好地理解它的特性和優勢。 ...
  • 1. 為什麼要拆分資料庫? 單體項目在構建之初,資料庫的負載和數據量都不大,所以不需要對資料庫做拆分,小型財務系統、文書系統、ERP系統、OA系統,用一個MySQL資料庫實例基本就夠用了。 就像《淘寶技術這十年》裡面說到的,電商業務的數據量增長飛快,所以最開始的PHP+MySQL的架構已經不能滿足實 ...
  • 【Flutter】如何優美地實現一個懸浮NavigationBar 最近寫代碼的時候遇到了一個如下的需求: 整體來說,底部的條是一個浮動的懸浮窗,有如下的三個按鈕: 點擊左邊的要進入“主頁” 點擊中間的按鈕要進行頁面跳轉,能夠進入“創作頁” 點擊右邊的按鈕切換到“個人中心”頁 使用Overlay來實 ...
  • 經過 Adobe 工程師多年來的努力,並與 Chrome 等瀏覽器供應商密切合作,通過 WebAssembly + Emscripten、Web Components + Lit、Service Workers + Workbox 和新的 Web API 的支持,終於在近期推出了 Web 版 Pho ...
  • 主要增加對容器創建 MySQL、Mongo 時對 數據文件,日誌,配置,網路,時區,埠映射,密碼 的配置,更貼合生產環境的實際使用 ...
  • 軟體設計原則 GRASP 通用職責分配軟體模式 來自 Craig Larman 的軟體設計書《UML 和模式應用》,Larman 在書中提出軟體設計的關鍵任務是職責分配,並提煉總結出 9 種 (5 種核心 +4 種擴展) 軟體職責分配模式,這些模式是比 GoF 設計模式更抽象的元模式。 信息專家 ( ...
  • 本文記錄了穩定性摸排過程中的一些思考和沉澱。 前言 在之前寫了篇文章《上線十年,81萬行Java代碼的老系統如何重構》,在文章後有同學留言問“這麼複雜的改動,質量是如何應對的”,是一個特別好的問題,當時只是從現有的一些監控、測試、卡口手段上進行了回答。但在回答過程當中就在思考一個問題,交接過來的老代 ...
  • 前言 在日常的開發中,我們經常使用key-value鍵值對的HashMap,其使用哈希表實現,用空間換取時間,提升查詢性能 但在多線程的併發場景中,HashMap並不是線程安全的 如果想使用線程安全的,可以使用ConcurrentHashMap、HashTable、Collections.synch ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...