中的實(shí)戰(zhàn)應(yīng)用與避坑指南)
做Flutter開發(fā)這幾年我越來越覺得Dart是一門被低估的語言。尤其是Dart 3正式把Pattern Matching模式匹配帶進(jìn)語法核心之后很多原本要寫大段if/else的場(chǎng)景一下子清爽了很多。最近在適配鴻蒙HarmonyOS/OpenHarmony設(shè)備時(shí)我更是把這套能力用在了幾個(gè)高頻場(chǎng)景里——狀態(tài)分發(fā)、數(shù)據(jù)解析、表單校驗(yàn)。這篇文章就是想把這個(gè)主題完整梳理一遍Flutter跨平臺(tái)開發(fā)里Pattern Matching到底怎么用、用在哪兒、踩過哪些坑給正在做鴻蒙適配或者剛接觸Dart 3的同行一個(gè)參考。很多人在聊跨平臺(tái)時(shí)只盯著渲染引擎和平臺(tái)通道卻忽略了語言本身帶來的生產(chǎn)力提升。Flutter跨平臺(tái)鴻蒙開發(fā)這件事本質(zhì)上是用同一套Dart代碼跑在不同系統(tǒng)上而模式匹配恰恰是Dart 3里最能減少樣板代碼、讓邏輯表達(dá)更貼近真實(shí)業(yè)務(wù)語義的特性之一。它適合所有寫Flutter的人尤其是那些正在做鴻蒙適配、需要處理大量狀態(tài)判斷和數(shù)據(jù)結(jié)構(gòu)拆解的業(yè)務(wù)開發(fā)者。1. 為什么在鴻蒙跨平臺(tái)場(chǎng)景下聊Pattern Matching1.1 從Dart 3說起模式匹配不是錦上添花Dart 3.0在2023年正式發(fā)布最核心的語法更新就是引入了Pattern Matching。很多人第一反應(yīng)是“這不就是switch增強(qiáng)嗎”實(shí)際上它比switch的范疇大得多。模式匹配是一種“按形狀解構(gòu)數(shù)據(jù)”的能力你可以用它來檢查一個(gè)值是否匹配某種結(jié)構(gòu)、從對(duì)象中提取字段、在匹配的同時(shí)完成變量綁定甚至組合出復(fù)雜的匹配規(guī)則。在Flutter跨平臺(tái)鴻蒙開發(fā)的語境下這套能力最大的價(jià)值是讓業(yè)務(wù)邏輯代碼跟平臺(tái)解耦得更徹底。傳統(tǒng)的做法里我們常常通過大量if/else去判斷狀態(tài)、處理返回結(jié)果代碼里堆滿了臨時(shí)變量和強(qiáng)制類型轉(zhuǎn)換。而模式匹配把“判斷取值轉(zhuǎn)換”合并成一條聲明式語句你寫的是“我想匹配什么形狀的數(shù)據(jù)”而不是“一步步去拆開這個(gè)數(shù)據(jù)”。我打個(gè)比方。傳統(tǒng)寫法像你收到一個(gè)快遞先拿刀劃開膠帶再翻開紙箱再撕開泡沫最后才看到里面的東西。模式匹配則是直接告訴快遞員“我要的是那個(gè)紅色盒子里的小號(hào)螺絲刀”整個(gè)拆箱過程由語言幫你完成。這個(gè)類比放到代碼里就是減少了一堆中間變量、類型斷言和防御式寫法。1.2 它能在鴻蒙Flutter項(xiàng)目里解決什么實(shí)際問題鴻蒙生態(tài)下的Flutter開發(fā)場(chǎng)景和安卓/iOS有一個(gè)明顯的不同你面對(duì)的可能是手機(jī)、平板、智慧屏、車機(jī)等不同形態(tài)的設(shè)備這意味著數(shù)據(jù)結(jié)構(gòu)和交互狀態(tài)會(huì)更加多樣化。比如同樣一段用戶信息在手機(jī)端可能是完整字段在智慧屏上可能只有昵稱和頭像同樣一個(gè)網(wǎng)絡(luò)請(qǐng)求結(jié)果可能是成功數(shù)據(jù)、可能是錯(cuò)誤碼、也可能是一段提示文案。用傳統(tǒng)的if/else去處理這種多分支、多形態(tài)的數(shù)據(jù)代碼很快就會(huì)變成一鍋粥。而模式匹配天然適合處理這種場(chǎng)景——它允許你把每一種“形狀”的匹配規(guī)則平鋪開每個(gè)分支只關(guān)注自己關(guān)心的字段讀起來就像一張對(duì)照表。另外Flutter跨平臺(tái)鴻蒙開發(fā)里經(jīng)常要處理平臺(tái)通道傳回來的數(shù)據(jù)。來自鴻蒙側(cè)的方法調(diào)用返回值經(jīng)過JSON編碼后到了Dart側(cè)類型往往是Object/Map/List混雜的過去需要一堆runtime類型檢查。模式匹配的“類型判等模式”可以直接把這些檢查寫成一行省掉很多重復(fù)的類型判斷樣板。還有一個(gè)讓我印象很深的點(diǎn)可空性。Dart的空安全已經(jīng)很成熟了但空值處理在日常代碼里依然頻繁。模式匹配里有專門的“空檢查模式”和“邏輯或模式”可以把“非空滿足條件”這類組合判斷壓縮到一個(gè)分支里這在處理設(shè)備能力差異、用戶配置缺失等邊界情況時(shí)特別順手。2. 模式匹配的核心語法一次講明白2.1 最常用的三類邏輯或、空檢查、邏輯與先從最直觀的開始。邏輯或模式用||符號(hào)連接表示“匹配任意一個(gè)即可”。比如一個(gè)登錄頁的狀態(tài)可能是驗(yàn)證碼登錄、也可能是密碼登錄你可以寫switch (loginType) { case sms || password: print(需要走身份校驗(yàn)); case biometric: print(生物識(shí)別登錄); }空檢查模式用?后綴表示意思是“這個(gè)值非空才進(jìn)入分支”。它的場(chǎng)景非常典型——你想獲取一個(gè)可能為空的配置為空就取默認(rèn)值String? nickname user.nickname; switch (nickname) { case ?: print(昵稱為空顯示默認(rèn)名); default: print(昵稱是$nickname); }注意這里不是判斷nickname null而是反過來的“非空檢查”。在空安全體系里這種寫法比if (nickname ! null)更貼近“我關(guān)心的是這個(gè)值是否真的存在”這個(gè)意圖。邏輯與模式用連接它可以同時(shí)匹配多個(gè)條件并且在匹配的同時(shí)完成變量綁定。比如你想判斷一個(gè)點(diǎn)坐標(biāo)是否在特定區(qū)域同時(shí)拿到坐標(biāo)值if (point is (int x, int y) x 0 y 0) { print(第一象限的點(diǎn)($x, $y)); }這三個(gè)模式是我在日常開發(fā)里用得最多的。它們本身不難但組合起來能在很多場(chǎng)景替代大段的條件疊加。2.2 類型判等與解構(gòu)告別手寫字段拆分類型判等模式可能是模式匹配里最實(shí)用的一類。它的核心思想是匹配某個(gè)類型然后直接解構(gòu)出內(nèi)部字段。Dart里的記錄類型Record和這個(gè)結(jié)合得非常好比如(String name, int age) user (張三, 18); switch (user) { case (var name, var age): print(姓名$name年齡$age); }這會(huì)自動(dòng)把記錄的字段綁定到name和age變量上不用再寫user.$1、user.$2。如果你處理的是JSON解析后的Map同樣可以直接用對(duì)象模式解構(gòu)if (json case {name: String name, age: int age}) { print($name 今年 $age 歲); }這種寫法把“判斷key存在且類型正確”和“取值賦值”合并成一步以前需要三五行甚至要寫輔助函數(shù)的事情現(xiàn)在一行搞定。在鴻蒙Flutter開發(fā)里平臺(tái)通道傳回的Map通常嵌套很深用這種方式可以把一層層的數(shù)據(jù)解構(gòu)寫得很直觀。對(duì)象模式可以看作是類型判等模式的延伸。它通過類的構(gòu)造函數(shù)來匹配字段比如class User { final String name; final int age; User(this.name, this.age); } void printUserInfo(Object obj) { if (obj case User(name: var name, age: var age)) { print(匹配到User$name$age); } }2.3 列表、Map、通配符組合起來才強(qiáng)大列表模式可以直接匹配List的長(zhǎng)度和元素結(jié)構(gòu)。比如要解析一個(gè)固定格式的消息協(xié)議前面是消息類型、后面是數(shù)據(jù)你可以寫ListObject message [text, hello]; switch (message) { case [text, var content]: print(文本消息$content); case [image, var url, var width]: print(圖片消息$url寬度$width); }這在處理鴻蒙端通過MethodChannel傳來的參數(shù)列表時(shí)特別有用因?yàn)槠脚_(tái)通道的參數(shù)本質(zhì)上就是List。Map模式我們已經(jīng)見過了它支持{key: pattern}的形式也支持用...匹配剩余字段。通配符_在任意位置都能用表示“我不關(guān)心這個(gè)值是什么”。組合起來可以寫出非常豐富的匹配規(guī)則switch (result) { case {code: 200, data: {items: [_, _, ...]}}: print(成功且有至少兩個(gè)數(shù)據(jù)項(xiàng)); case {code: 401, ...}: print(未授權(quán)其他字段不關(guān)心); }有人可能會(huì)擔(dān)心這種寫法會(huì)增加理解成本。我的經(jīng)驗(yàn)是在數(shù)據(jù)結(jié)構(gòu)相對(duì)穩(wěn)定的內(nèi)部接口上組合模式匹配能讓代碼變得非常清晰但如果接口字段本身不穩(wěn)定那還是要謹(jǐn)慎使用別為了炫技把數(shù)據(jù)流寫成了謎語。3. 在Flutter鴻蒙業(yè)務(wù)里的四個(gè)落地場(chǎng)景3.1 狀態(tài)管理里的邏輯收斂Flutter的狀態(tài)管理常用sealed class定義一整套狀態(tài)配合Bloc或Riverpod使用。在引入模式匹配之前你要處理一個(gè)聯(lián)合狀態(tài)只能一層層if/else下去?,F(xiàn)在可以這樣sealed class HomeState {} class Loading extends HomeState {} class Error extends HomeState { final String message; } class Data extends HomeState { final ListItem items; } void render(HomeState state) { switch (state) { case Loading(): showLoading(); case Error(message: var msg): showError(msg); case Data(items: var list): showList(list); } }這里的case Data(items: var list)會(huì)同時(shí)完成類型檢查、字段綁定和分支執(zhí)行編譯器還會(huì)提示你是不是遺漏了某個(gè)子類型。在鴻蒙多設(shè)備場(chǎng)景下狀態(tài)種類往往更多比如還要區(qū)分“權(quán)限未授予”“設(shè)備離線”等這種寫法的可維護(hù)性優(yōu)勢(shì)會(huì)更明顯。我之前看過不少鴻蒙Flutter項(xiàng)目狀態(tài)處理喜歡用枚舉加一堆switch枚舉值一變每個(gè)switch都要跟著改。用sealed class 模式匹配之后加一個(gè)狀態(tài)只需要改定義和新增一個(gè)分支而且編譯器會(huì)幫你兜底漏掉分支直接編譯報(bào)錯(cuò)。3.2 網(wǎng)絡(luò)層JSON解析與錯(cuò)誤分流Flutter跨平臺(tái)鴻蒙開發(fā)里網(wǎng)絡(luò)請(qǐng)求返回的JSON結(jié)構(gòu)千奇百怪。有的接口成功和失敗的數(shù)據(jù)結(jié)構(gòu)完全不同有的錯(cuò)誤碼藏在多層嵌套里。模式匹配能把這些解析邏輯壓得非常薄。Futurevoid handleResponse(Object? json) async { switch (json) { case {code: 0, data: {list: List items}}: await cacheItems(items); case {code: int code, message: String msg}: log(業(yè)務(wù)錯(cuò)誤$code $msg); case null: log(返回為空); } }比較妙的是{code: 0, data: {list: List items}}這行它同時(shí)校驗(yàn)了第一層、第二層的結(jié)構(gòu)把items綁定成了List類型。以前要寫三層嵌套的if判斷才能拿到這個(gè)List而且還要手動(dòng)類型斷言。另外錯(cuò)誤信息的分流也可以用模式匹配做得很優(yōu)雅。比如后端可能返回HTTP層錯(cuò)誤、業(yè)務(wù)層錯(cuò)誤、超時(shí)異常三種情況你可以把它們映射成一個(gè)統(tǒng)一的處理結(jié)果Object? result await api.request(); final handled switch (result) { {code: 0} 成功, {code: 2001} 余額不足, {code: 2002} 登錄過期, TimeoutException() 網(wǎng)絡(luò)超時(shí), _ 未知錯(cuò)誤, };這里的switch表達(dá)式會(huì)直接返回一個(gè)值比傳統(tǒng)的語句式switch更加緊湊。我自己在項(xiàng)目中實(shí)測(cè)下來這種寫法不僅短而且每個(gè)case的意圖非常明確別人接手代碼的時(shí)候幾乎不需要額外注釋。3.3 表單校驗(yàn)用模式匹配替代一連串if在表單校驗(yàn)這個(gè)場(chǎng)景我真的被模式匹配圈粉了。以前寫表單校驗(yàn)無非是“這個(gè)字段為空嗎”“這個(gè)字段格式對(duì)不對(duì)”串成一長(zhǎng)串if/else每個(gè)字段一個(gè)if塊改一個(gè)邏輯要反復(fù)滾動(dòng)屏幕。有了模式匹配可以把所有校驗(yàn)規(guī)則聲明式地列出來String? validateForm({ required String? username, required String? phone, required String? password, }) { return switch ((username, phone, password)) { (null, _, _) 用戶名不能為空, (_, null, _) 手機(jī)號(hào)不能為空, (_, _, null) 密碼不能為空, (var name, var phoneNum, var pwd) when name.length 3 用戶名至少3位, (var name, var phoneNum, var pwd) when !RegExp(r^1\d{10}$).hasMatch(phoneNum) 手機(jī)號(hào)格式不正確, (var name, var phoneNum, var pwd) when pwd.length 6 密碼至少6位, _ null, }; }這段代碼的可讀性非常高——你一眼就能看出每個(gè)分支對(duì)應(yīng)哪個(gè)校驗(yàn)規(guī)則。when子句可以在模式匹配的基礎(chǔ)上追加額外的條件判斷比如when name.length 3。而且因?yàn)橛昧藃ecord同時(shí)攜帶三個(gè)字段校驗(yàn)邏輯之間互不干擾以后再增加一個(gè)“確認(rèn)密碼”字段也只需要在record里加一個(gè)元素、加一個(gè)case分支。特別注意模式匹配適用于這種“規(guī)則相對(duì)固定、字段數(shù)量有限”的場(chǎng)景。如果你的表單是動(dòng)態(tài)生成、字段列表不固定那還是得用循環(huán)遍歷配置表的方式去做不要硬套模式匹配。3.4 事件分發(fā)與路由跳轉(zhuǎn)讓代碼更貼近業(yè)務(wù)語義路由跳轉(zhuǎn)和事件分發(fā)往往是跨平臺(tái)App里最容易長(zhǎng)成“屎山”的部分。尤其是在鴻蒙Flutter項(xiàng)目里一個(gè)頁面可能要響應(yīng)來自不同模塊的多個(gè)事件每個(gè)事件攜帶的參數(shù)還不同。用模式匹配處理事件分發(fā)本質(zhì)上就是把“事件的形狀”作為分發(fā)的依據(jù)void onEvent(AppEvent event) { switch (event) { case OpenPage(route: profile, userId: var id): navigator.push(UserProfilePage(userId: id)); case OpenPage(route: settings): navigator.push(SettingsPage()); case UpdateData(data: {type: todo, items: var items}): todoStore.update(items); case RefreshToken(newToken: var token): authStore.updateToken(token); } }這里的關(guān)鍵點(diǎn)是事件類內(nèi)部可以攜帶任意結(jié)構(gòu)的數(shù)據(jù)而分發(fā)邏輯完全不需要去理解事件的“全部?jī)?nèi)容”只需要匹配自己關(guān)心的字段。這對(duì)鴻蒙多設(shè)備適配也有幫助——不同設(shè)備的頁面棧不一樣有些設(shè)備可能不支持某些路由你只需要在對(duì)應(yīng)分支里加設(shè)備判斷或者干脆讓對(duì)應(yīng)的case不匹配即可。我在項(xiàng)目里還喜歡把模式匹配和擴(kuò)展函數(shù)組合起來給event類寫一個(gè)when分發(fā)器讓調(diào)用方可以這樣寫event.when( openPage: (route, userId) ..., updateData: (type, items) ..., refreshToken: (token) ..., );本質(zhì)上這種“事件形狀驅(qū)動(dòng)分發(fā)”的思路比傳統(tǒng)的一長(zhǎng)串is判斷要容易擴(kuò)展。新增一種事件類型你只需要新增一個(gè)case老代碼完全不用動(dòng)。4. 常見問題與排查技巧實(shí)錄4.1 編譯報(bào)錯(cuò)版本和SDK要卡準(zhǔn)模式匹配是Dart 3.0的語法如果你的Flutter SDK還停留在2.x那這些代碼一個(gè)都跑不起來。我在踩坑初期就遇到過這個(gè)問題——明明本地Dart版本已經(jīng)支持了但項(xiàng)目因?yàn)闅v史原因還鎖在舊環(huán)境一編譯就報(bào)語法錯(cuò)誤。核心排查思路是三步檢查Flutter版本flutter --version確保Dart版本是3.0以上。推薦直接用最新的穩(wěn)定版Flutter因?yàn)轼櫭蛇m配插件通常會(huì)跟進(jìn)新版本。檢查項(xiàng)目的SDK約束打開pubspec.yaml確認(rèn)environment里寫了sdk: 3.0.0 4.0.0之類的約束。檢查是否啟用了experimental特性Dart 3穩(wěn)定之后不用再開任何實(shí)驗(yàn)開關(guān)但如果你的依賴?yán)锘熘f包可能會(huì)提示某些語法不被支持。另外模式匹配在早期版本里有些細(xì)節(jié)和現(xiàn)在不太一樣。比如switch表達(dá)式是Dart 3.0正式引入的但某些內(nèi)嵌模式的支持度在不同小版本上有差異。如果你發(fā)現(xiàn)一個(gè)字面量模式在某個(gè)版本上編譯不過先去查一下那個(gè)版本的changelog別急著改代碼。4.2 可讀性陷阱不要為了炫技而匹配模式匹配寫起來很爽但它有非常明顯的雙刃劍效應(yīng)。我見過一些代碼把匹配嵌套了四五層一個(gè)case里既有l(wèi)ist解構(gòu)又有map解構(gòu)還加上when子句最后讀起來比原來的if/else還難懂。我的個(gè)人準(zhǔn)則是只有分支數(shù)據(jù)結(jié)構(gòu)本身天然是嵌套的才用嵌套匹配。比如JSON解析、平臺(tái)通道參數(shù)解析這些天然就是嵌套結(jié)構(gòu)。如果業(yè)務(wù)邏輯的每一步判斷都是獨(dú)立的比如“為空”“格式錯(cuò)”“長(zhǎng)度不夠”優(yōu)先用record 多個(gè)平級(jí)case不要強(qiáng)行嵌套。一個(gè)case里超過兩個(gè)或者超過兩層解構(gòu)就必須停下來想想能不能拆開寫。代碼是寫給人看的模式匹配的作用是“減少樣板代碼、增強(qiáng)可讀性”不是“把邏輯壓縮成一行”。如果同事接手你的代碼需要花十分鐘才能搞懂一個(gè)case在干什么那這個(gè)寫法就失敗了。還有一點(diǎn)值得提醒模式匹配的變量綁定作用域和普通代碼不太一樣。在同一個(gè)case里綁定同名變量是允許的但如果你在多個(gè)case里用同一個(gè)變量名可能會(huì)在重構(gòu)時(shí)造成混淆。我建議case內(nèi)部變量名盡量語義化別貪圖短命名。4.3 性能考量與工具鏈配合模式匹配在Dart里的實(shí)現(xiàn)絕大多數(shù)情況下編譯期就能優(yōu)化掉運(yùn)行開銷幾乎可以忽略。但有一個(gè)場(chǎng)景要注意如果你的匹配對(duì)象是一個(gè)巨大的record或Map并且每個(gè)case都嘗試解構(gòu)整個(gè)對(duì)象這會(huì)產(chǎn)生不必要的一次性分配。舉個(gè)實(shí)際例子如果你在循環(huán)里對(duì)每個(gè)元素執(zhí)行一個(gè)包含Map模式匹配的switch且Map本身很大那每次匹配都會(huì)創(chuàng)建一個(gè)新的臨時(shí)Map來參與匹配。這在單個(gè)數(shù)據(jù)量小的時(shí)候無所謂但如果是上萬條的列表就有可能會(huì)出現(xiàn)性能抖動(dòng)。我的建議是熱路徑比如每幀都要執(zhí)行的代碼里避免對(duì)大Map做模式匹配??梢韵劝研枰臄?shù)據(jù)提取成小record再做匹配。模式匹配更適合用在下層業(yè)務(wù)邏輯里UI層構(gòu)建和渲染回調(diào)盡量保持輕量。用flutter analyze和IDE的靜態(tài)檢查來輔助判斷——有時(shí)候工具會(huì)提示你某些case永遠(yuǎn)不會(huì)匹配這個(gè)一定要認(rèn)真對(duì)待通常說明你的數(shù)據(jù)流和預(yù)期已經(jīng)不一致了。另外鴻蒙Flutter開發(fā)里有一個(gè)特殊場(chǎng)景要注意平臺(tái)通道返回的數(shù)據(jù)有時(shí)并不完全遵循Dart的類型系統(tǒng)可能會(huì)有意料之外的null或者類型轉(zhuǎn)換異常。模式匹配在遇到類型不匹配的case時(shí)會(huì)直接落到default分支不會(huì)拋出TypeError。這個(gè)特性既是優(yōu)點(diǎn)也是坑——如果你沒有寫default分支某些異常數(shù)據(jù)會(huì)被靜默忽略導(dǎo)致bug很難查。我的做法是模式匹配的switch語句永遠(yuǎn)帶上default或者在switch表達(dá)式里用_ 默認(rèn)值兜底至少打個(gè)日志。5. 模式匹配在鴻蒙Flutter中的擴(kuò)展思考這套能力還有一個(gè)容易被忽略的用法與Dart的records和sealed class結(jié)合構(gòu)建一個(gè)完全面向模式匹配的領(lǐng)域模型層。比如你在鴻蒙Flutter里做多端同步可以把每一條同步指令建模成一個(gè)sealed class然后用一個(gè)統(tǒng)一的match函數(shù)去分發(fā)處理。這樣平臺(tái)差異都被封在了建模層業(yè)務(wù)層看到的只有清晰的類型和匹配規(guī)則。再往深了走模式匹配還能配合擴(kuò)展方法實(shí)現(xiàn)類似“訪問者模式”的效果。比如你有一個(gè)數(shù)據(jù)結(jié)構(gòu)需要根據(jù)設(shè)備形態(tài)渲染不同的組件傳統(tǒng)的做法是到處寫if (deviceType ...)現(xiàn)在可以定義一組模式匹配的助手方法讓每種設(shè)備類型在各自的case里返回自定義widget。這樣平臺(tái)適配邏輯被集中管理不會(huì)散落在各個(gè)頁面里。我做鴻蒙適配這段時(shí)間的最大體會(huì)是跨平臺(tái)開發(fā)最大的成本從來不是“能不能跑”而是“邏輯代碼能不能在不同平臺(tái)上保持一致地演進(jìn)”。模式匹配讓業(yè)務(wù)邏輯的每個(gè)分支都變成了可見的、結(jié)構(gòu)化的case這比一長(zhǎng)串條件判斷更容易測(cè)試、更容易review、也更容易在新平臺(tái)上復(fù)現(xiàn)相同的行為。6. 寫在最后的幾點(diǎn)實(shí)操心得模式匹配這東西光看語法會(huì)覺得“哦不過如此”但真正用起來之后你會(huì)慢慢發(fā)現(xiàn)自己在換一種方式思考代碼結(jié)構(gòu)。以前寫判斷是先想“這個(gè)值可能是什么”然后逐個(gè)檢查現(xiàn)在寫匹配是先想“數(shù)據(jù)應(yīng)該長(zhǎng)什么形狀”然后把每個(gè)形狀對(duì)應(yīng)的處理寫清楚。這是思維方式上的轉(zhuǎn)變代碼只是載體。建議剛開始接觸的朋友別急著重構(gòu)現(xiàn)有代碼先在新的需求里試著用起來。比如下次寫一個(gè)網(wǎng)絡(luò)請(qǐng)求解析或者寫一個(gè)表單校驗(yàn)逼自己用switch表達(dá)式寫一版對(duì)比一下舊寫法的差異。用不了幾次你就能找到手感。最后再分享一個(gè)小習(xí)慣我在Flutter鴻蒙項(xiàng)目里會(huì)把所有模式匹配相關(guān)的case集中放在一起加一個(gè)“匹配規(guī)則說明書”的注釋塊。比如某個(gè)狀態(tài)容器后面用注釋列出所有可能的狀態(tài)形狀和對(duì)應(yīng)含義。這樣后來的人改代碼時(shí)不用去翻數(shù)據(jù)源定義光看注釋就能理解這些case的前因后果。這個(gè)習(xí)慣幫我的團(tuán)隊(duì)省下了很多溝通時(shí)間分享給你參考。