Dart 3.0 语法新特性 | switch 匹配加强

news2024/9/28 11:14:30

theme: cyanosis

一、 重新审视 switch 关键字

众所周知, switch 关键字用于流程控制: 可以基于一个对象进行匹配,并通过 case 关键字产生分支语句,进行不同的逻辑处理。其中有一个非常值得注意,使用者很容易忽略的一点:

Dart3.0 之前: 分支中的 case 关键字后的对象必须是 常量

1. Dart 3.0 之前的 switch 关键字

在日常开发中,switch 匹配的对象,一般是 int/double/String/enum。 比如下面的 foo1 方法中,对 int 型的变量通过 switch 进行匹配,根据 case 情况,进行不同对应的逻辑处理:

dart void foo1(int value) { switch (value) { case 0: print("=====零====="); break; case 1: print("=====壹====="); break; default: print("=====無====="); } }


在 Dart3.0 之前,case 后就可以放置任何类型的 常量 ,比如下面定义的 Number 类型。只不过这种写法并不是很常用,Dart 3.0 之前的 switch 语法点也就止步于此:

```dart void foo2(Number value) { // switch 在 Dart 3.0.0 之前就一直可以匹配任何对象 switch (value) { case const Number(0): print("=====零====="); break; case const Number(1): print("=====壹====="); break; default: print("=====無====="); } }

class Number { final int value;

const Number(this.value); } ```


2. Dart 3.0 之后的 switch 关键字

在 Dart 3.0 之后引入了模式匹配 Patterns ,而本质上来说 switch 关键字的作用就是在进行匹配校验。所以 Patterns 的引入,极大加强了 switch 的语法特性。下面通过一个小例子体会一下:

比如今天是 2023 年 6 月 9 日,现在想要拓展一下 DateTime 类型,给一个 describe 方法用于输出 DateTime 对象和今天的天数差值情况。比如 6 月 12 日输出 3 天后 ; 6 月 8 号输出 昨天

```dart void main() { DateTime(2023, 6, 5).describe(); DateTime(2023, 6, 8).describe(); DateTime(2023, 6, 9).describe(); DateTime(2023, 6, 12).describe(); }

--->[日志输出]---- 2023/6/5 是 4 天前 2023/6/8 是 昨天 2023/6/9 是 今天 2023/6/12 是 3 天后 ```

如下所示,对 DateTime 类进行拓展,添加了一个 describe 方法,用于处理输出逻辑。其中用到了 switch + 模式匹配的特性:

dart extension DescribeDate on DateTime { void describe() { DateTime now = DateTime.now(); Duration diff = this.difference(DateTime(now.year, now.month, now.day)); String result = switch (diff) { Duration(inDays: -1 ) => '昨天', Duration(inDays: 0 ) => '今天', Duration(inDays: 1 ) => '明天', Duration(inDays: int d) => d < 0 ? '${d.abs()} 天前' : '$d 天后', }; print("$year/$month/$day 是 $result"); } }

一个很明显的特征是: switch 关键字的分支语句可以作为返回值。而且分支由 模式匹配 Patterns 进行创建,还不了解 Patterns 的朋友,可以转到上一篇 《 Dart 3.0 语法新特性 | 模式匹配 Patterns》 。 下面红框中的 => 左侧的部分是对普通对象的模式匹配,其中 inDays 是 Duration 的 get 方法,所以支持对 inDays 名称的模式匹配:

image.png


二、从 switch 来看 Patterns 的种类

在上一篇,我们了解了支持 Patterns 模式匹配的几种类型 (Type)。 但模式匹配并不仅止于此,下面将通过 switch 语句来看一下其他的 Patterns 的种类:

image.png


1. 常量与解构变量

在本篇一开始时就介绍了 switch 的分支语句是对 常量 的匹配, 既然可以被 switch 匹配,就可以视为 Patterns 模式, 这就不过多赘述了。
如下所示, foo2 中传入一个 dynamic 类型的值,在 switch 中可以进行匹配:在 case 中解构 value 值,这样就可以根据变量类型匹配,进入不同的分支进行处理:

```dart void main(){ foo2((1,1)); // 打印 int+int foo2((1,"hello")); // 打印 int+String foo2(5); // 打印 default }

// 变量 Patterns void foo2(dynamic value){ switch (value) { case (int a, String b): print("int+String"); break; case (int a, int b): print("int+int"); break; default: print("default"); } } ```


2. 符号与关键字的 Patterns 模式匹配

除了类型之外,符号和某些关键字也可以对若干个子模式进行连接,形成新的 Patterns 模式。 这很像正则表达式,若干个子正则可以通过符号连接成新正则。 连接符包括:

逻辑运算符: 或 || 、 与 &&

dart int age = 12; var isAllow = switch (age) { 16 || 17 || 18 => true, _ => false, };


关系运算符: > 、>= 、< 、<= 、 == 、!=

```dart int score = 69; var info = switch (score) {

=40 && < 60 => 'D', == 100 => 'A+', = 90 && < 100 => 'A', = 80 && < 90 => 'B', = 70 && < 80 => 'C', _ => 'E', }; ```

注: _ 可以表示其他未匹配的情况,相当于 default 分支的作用。


强制类型转换 asobject?object!

这三者简单了解一下,也可以作为 Patterns 加入匹配规则体系:

```dart (num, Object) record = (1, 's'); var (i as int, s as String) = record; print("========($i,$s)=========");

switch (value) { case var s?: print('s 非空类型:$s'); default: print('default'); }

(int?, int?) position = (2, 3); var (x!, y!) = position; print("========($x,$y)========="); ```


三、从 switch 和 Patterns 为我们带来了什么

可能很多人看着 Patterns 匹配感觉很迷茫,这是什么玩意,感觉花里胡哨,感觉挺厉害又没什么大用的样子。这可能是你并没有明白 Patterns 是干什么用的,简单来说 Patterns 是定义了一套语法级的匹配规则。

下面拿出介绍密封类时的那个小案例,理解一些: 登陆界面的认证状态 AuthState,有如下三种子状态

  • 认证中 AuthLoading
  • 认证成功 AuthSuccess
  • 认证失败 AuthFailure

```dart sealed class AuthState{} //创建密封类

class AuthLoading extends AuthState{}

class AuthSuccess extends AuthState{ final String user; final String token;

AuthSuccess(this.user, this.token); }

class AuthFailure extends AuthState{ final String error; AuthFailure(this.error); } ```

如下是基于 AuthState 对象构建界面的逻辑:其中使用了 switch 进行匹配,并将其作为返回值;每个分支的左侧是 Patterns ,当 state 对象匹配时进入对应分支返回结果。

注意: 这里的 AuthLoading() 并不是构造对象,而是一般类型的 Patterns 语法。匹配到对应类型,就可以访问对应子类型的数据。

dart String buildByAuthState(AuthState state){ return switch(state){ AuthLoading()=> 'AuthLoading View', AuthSuccess()=> 'AuthSuccess View:${state.user}', AuthFailure()=> 'AuthFailure View:${state.error}', }; }

如下也可以通过 变量 Patterns 进行匹配:

dart String buildByAuthState3(AuthState state){ return switch(state){ AuthLoading loading => 'AuthLoading View', AuthSuccess success => 'AuthSuccess View:${success.user}', AuthFailure fail => 'AuthFailure View:${fail.error}', }; }

或者将变量通过 _ 进行匿名处理:

dart String buildByAuthState1(AuthState state){ return switch(state){ AuthLoading _ => 'AuthLoading View', AuthSuccess _ => 'AuthSuccess View:${state.user}', AuthFailure _ => 'AuthFailure View:${state.error}', }; }

就像不同的正则表达式,可以完成相同的匹配目的。合理地运用匹配规则,可以方便我们便捷地处理逻辑。否则上面的代码逻辑就需要用 if 分支语句处理,会增加很多无意义的代码。所以面对一个新事物,应该去思考它存在的必要性,是为了解决什么问题而出现的,而不是拘泥于语法点,而死记硬背。

image.png

Dart 3.0 的新语法点就介绍差不多了,这里整理一下相关文章。那本文就到这了。谢谢观看~

  • 《Dart 3.0 语法新特性 | Records 记录类型 (元组)》
  • 《Dart 3.0 语法新特性 | 类型修饰符 Class modifiers》
  • 《Dart 3.0 语法新特性 | 模式匹配 Patterns》
  • 《Dart 3.0 语法新特性 | switch 匹配加强》 本文

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/671262.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Jetpack Compose —— ProgressBar

Jetpack Compose的ProgressBar是一种用户界面组件&#xff0c;用于向用户展示长时间操作的当前进度。ProgressBar可以有两种形式&#xff1a;线性和环形&#xff0c;这两种形式都可以通过Jetpack Compose轻松实现。 注意&#xff1a;从Jetpack Compose 1.0版本开始&#xff0c…

ChatGPT使用的SSE技术是什么?

在现代web应用程序中&#xff0c;实时通信变得越来越重要。HTTP协议的传统请求/响应模式总是需要定期进行轮询以获得最新的数据&#xff0c;这种方式效率低下并且浪费资源。因此&#xff0c;出现了一些新的通信技术&#xff0c;如WebSocket和SSE。但是&#xff0c;GPT为什么选择…

R语言学习4:比例的假设检验

一、实验目的 1. 掌握理解两个总体比例假设检验的相关概念。 2. 掌握理解两个总体比例假设检验的相关方法。 3. 熟悉R语言等语言的集成开发环境。 二、实验分析与内容 完成教材P98的第4题 在一个流行病事件中,A地区656 例病人中完全康复了474人,B地区568例病人中完全康复了…

k8s delete namespace Terminating

版本情况 kubenetes版本: v1.19.10 docker版本: v20.10.6 一、问题经过 早上发现 kubectl delete ns时, 删除namespace一直处于Terminating状态 尝试加上--force参数&#xff0c;执行kubectl delete ns --force&#xff0c;也是一样Terminating 当时Terminating截图 1、猜测…

《网络安全0-100》低层协议安全性

低层协议安全性 IP协议 对于网络层&#xff0c;IP协议是其中一个非常重要的协议。网络层的IP地址相当于数据链路层的Mac地址。协议字段如下&#xff0c;每行4字节&#xff0c;总共4*520字节。 IP协议安全性&#xff1a;IP协议不能保证数据就是从数据包中给定的源地址发出的&am…

高速 AD/DA 实验

目录 高速 AD/DA 实验 1、简介 1.1、AD9708 芯片 1.2、AD9280 芯片 2、实验任务 3、硬件设计 4、程序设计 4.1、AD/DA 顶层模块代码 4.2、创建一个 ​​​​​​​ILA IP 核 4.3、创建一个ROM IP核&#xff0c;将 .coe 文件保存到生成的 Rom IP 核中 4.4、DA 数据发…

人工智能基础实验报告

蒙特卡洛算法 目 录 蒙特卡洛算法 1 概述&#xff1a; 1 思考步骤: 1 应用&#xff1a; 1 特点: 2 参 考 资 料 3 概述&#xff1a; 蒙特卡罗法&#xff08;Monte Carlo method&#xff09;也称统计模拟法、统计试验法。是把概率现象作为研究对象的数值模拟方法。是按抽样调…

【操作系统】CPU调度

目录 1.什么叫调度 2.调度的目标 3.进程调度方式 4.闲逛进程 5.典型的调度算法 5.1先来先服务(FCFS)调度算法 5.2短作业优先(SJF) 调度算法 5.3优先级调度算法 5.4高响应比优先调度算法 5.5时间片轮转调度算法 5.6多级队列调度算法 5.7多级反馈队列调度算法(融合了前…

Qgis基本操作之图层符号化和标注实战

目录 前言 一、基础数据 1、公共预算收入数据简介 2、省份数据简介 二、地图标注 1、百强县公共预算收入地图标注 2、省信息标注 三、地图符号化 1、百强县公共预算收入符号化 2、省数据符号化 总结 前言 在之前的Qgis中进行Shp和Excel属性连接实现百强县公共预算空间分…

MATLAB 之 图形对象及其句柄和图形窗口与坐标轴

这里写目录标题 一、图形对象及其句柄1. 图形对象2. 图形对象句柄的使用3. 图形对象属性3.1 属性名与属性值3.2 属性的操作3.3 图形对象的公共属性 二、图形窗口与坐标轴1. 图形窗口对象2. 坐标轴对象 一、图形对象及其句柄 MATLAB 的图形系统是面向图形对象的。图形对象是 MA…

Redis新功能

Redis 新功能 ACL 参考官网&#xff1a;https://redis.io/topics/acl 基本介绍 1、Redis ACL 是Access Control List&#xff08;访问控制列表&#xff09;的缩写&#xff0c;该功能根据可以执行的命令和可以访问的键来限制某些连接 2、在Redis 5 版本之前&#xff0c;Red…

使用python做一个批量重命名文件的小工具

&#x1f6f4; 放松 端午放假前的下午&#x1f644; 没事儿可做&#xff0c;一个准备开始弄的项目里面有大量的图片&#xff0c;但是名字都乱七八糟的&#xff0c;作为一个稍微带点强迫症的人看不下去。 既然如此&#xff0c;想直接重命名&#xff0c;可是Windows的重命名效果…

《XrayGLM:基于VisualGLM-6B微调训练对X光胸片进行医学诊断》学习分享与本地项目微调部署实践

XrayGLM据说是首个会看胸部X光片的中文多模态医学大模型&#xff0c;我最近也是因为关注这个所以就找时间学习了一下&#xff0c;顺便把学习资料对应记录分享一下。 官方提供了开源的项目&#xff0c;地址在这里&#xff0c;如下所示&#xff1a; 最近&#xff0c;通用领域的大…

MySQL - 第6节 - MySQL表的增删查改

1.MySQL表的增删查改概述 • 表的增删查改简称CRUD&#xff1a;Create&#xff08;新增&#xff09;&#xff0c;Retrieve&#xff08;查找&#xff09;&#xff0c;Update&#xff08;修改&#xff09;&#xff0c;Delete&#xff08;删除&#xff09;。 • CRUD的操作对象是对…

抖音小店有哪些常见扣分原因?如何避免在抖音小店中被扣分?

抖音小店现在已经成为了很多商家的首选电商平台&#xff0c;但是在使用抖音小店的过程中&#xff0c;也会出现一些扣分的情况。接下来&#xff0c;四川不若与众将为大家介绍抖音小店扣分的原因和避免办法。 一、抖音小店扣分原因 1. 服务不到位&#xff1a;商家没有及时回复用户…

2023-01-06 VMWare桥接网络配置.md

VMWare16 桥接网络配置 一 环境清单 VMWare 16虚拟机&#xff1a;Centos7宿主机&#xff1a;Windows 10 二 配置过程 查看宿主机的IP相关信息 ipconfig -all 配置虚拟网络编辑器 2.1 打开VMware Workstation Pro&#xff0c;点击左上角编辑-->虚拟网络编辑器 2.2 点击更改配…

CRM商机管理:提升客户体验和销售效率

如何利用CRM系统提升商机管理&#xff1f; 花点时间思考一下你的企业管理商机的方法&#xff0c;是否有以下情况&#xff1a; ● 不知道渠道中的商机是否可行。 ● 不知道应该关注哪些商机。 ● 花了几个小时或几天的时间来跟进商机。 ● 不知道赢得商机与失去商机的比例。 如…

【Kafka】Suppressed: java.nio.file.AccessDeniedException问题的解决

【Kafka】Suppressed: java.nio.file.AccessDeniedException问题的解决 目录 前言 一、错误发生的原因 二、问题如何解决 前言 今天在运行kafka时&#xff0c;出现了如下图的报错Suppressed: java.nio.file.AccessDeniedException&#xff0c;怎么启动也启动不起来。那此问…

C/C++的命令执行分析

背景 最近发现一个命令执行风险&#xff1b; 一开始提供修复建议&#xff0c;是对特殊字符进行过滤&#xff0c;但是业务侧没有办法过滤&#xff0c;因为输入点是没有办法限制的&#xff0c;然后提供另一个方案是将用户的输入写到配置文件中&#xff0c;然后再进行操作&#x…

LeetCode24. 两两交换链表中的节点+19. 删除链表的倒数第 N 个结点

24. 两两交换链表中的节点 题目描述&#xff1a; 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 输入&#xff1a;head [1…