Dart 3.0 语法新特性 | 模式匹配 Patterns

news2024/11/16 18:09:47

theme: cyanosis

一、 Patterns 是什么

下面是官方对 Patterns 特性的说明 patterns :\ 从下面的第一句中可以知道,Patterns 是一种语法级的特性,而语法特性是一种语言的根基。

Patterns are a syntactic category in the Dart language, like statements and expressions.\ Patterns 是 Dart 语言中的一个语法类别,就像语句和表达式一样。

从下面第二句话在可以看出,Pattern 和数据的特征匹配相关。

A pattern represents the shape of a set of values that it may match against actual values.\ Pattern 表示可能与实际值相匹配的一组值的特征。

在英文中 Pattern 一词有:模式、形式、图样的意思。说句题外话:String 字符串和 Regex 正则表达式都实现 Pattern 接口,就说明 Pattern 一词和模式匹配的渊源。这里强调一句:Dart 3.0 的 Patterns 语法和上面提及的 Pattern 类型没有半毛钱关系。

在日常开发中,我们使用的类型都是具有一定的结构特征,而结构正是类中数据的栖身之地。Patterns 像是一种在语法层面,对类型结构特征提取的规则,结合匹配来更方便地完成一些工作。在类型之中, Record、List、Map 三种类型,有着非常明显的结构特征:

```dart 记录 Record 类型 |--- 普通值 (v1, v2 ,...) |--- 命名值 (k1:v1,k2:v2 ,...)

列表 List 类型 |--- 值列表 [v1,v2,...]

映射 Map 类型 |--- 键值对 {k1:v1, k2:v2 ,...} ```


二、 Patterns 的解构能力

解构(Destructuring) 就是访问并提取对象的某些数据,为某些指定的变量进行赋值的过程。其中提取数据就需要运用到 Patterns 的匹配特性。下面通过几个小例子了解一下:

1.对 Record 类型的解构
  • 非命名 Record 的类型

如下 foo 中 : 默认情况下,想要访问记录对象中的数据,需要通过 $1$2 :

dart void foo(){ var user = ('toly',29); String name = user.$1; int age = user.$2; print('======$name====${age}==='); }

如下 foo1 中 : 可以使用 Patterns 的特性,直接将 user 对象解构,为 nameage 赋值。这就是 Patterns 最重要的能力之一,

dart void foo1() { var user = ('toly',29); var (name, age) = user; // 直接解构对象 print('======$name====${age}==='); }

Record 的解构语法是 :

var ( 变量 1 , 变量 2 , ... ) = Record 对象


  • 命名 Record 类型

对于元素被命名的 Record 类型而言, 可以通过如下 Patterns 语法进行解构。比如下面,一句代码就可以调试为 abc 三个变量赋值:

dart var position = (x:1,y:3, 'p0'); var (x:a, y:b ,c) = position; print('====$a====$b====$c====');

var ( k1: 变量 1, k2: 变量 2 , ... ) = Record 对象

对于命名的数值而言,可以通过 :key 进行简写。比如下面的 :x 含义就是 x:x ,表示:将右侧对象中的名称为 x 的数据,为左侧的 x 变量赋值。

dart var position = (x:1,y:3, 'p0'); var (:x,:y,d) = position; print('====$x====$y====$d====');

这样的好处是能少起个变量名,适合 起名困难症者;但与此同时,这样你无法为变量名起别的名字。


2. 对 List 和 Map 的解构

除了 Record 类型 ,还有 List 和 Map 也支持解构。效果上类似,都是访问对象的数据,并直接为变量赋值。List 的结构语法是 :

var [ 变量1, 变量2, ... ] = List 对象

dart void foo2(){ List<int> numList = [1, 2, 3]; var [a, b, c] = numList; print('====$a====$b====$c='); }

如下是对 Map 对象的解构,语法是:

var { key : 变量1, key: 变量2, ...} = Map 对象

dart void foo3(){ Map<String,dynamic> data = { 'name': 'toly', 'age': 29, }; var {'name': name,'age': age}= data; print('======$name====${age}==='); }


同理,对于 Map 元素组成的 List 列表,也可以通过对应的语法进行解构,只要左侧变量结构符合右侧对象结构即可 :

dart void foo4(){ var data = [ { 'name': 'toly', 'age': 29, }, { 'name': 'ls', 'age': 28, }, ]; var [{'name': name,'age': age},{'name': name1,'age': age2}] = data; print('======$name====${age}===$name1====${age2}===='); }


3. 对普通对象的解构

除了可以解构特定的对象之外,还可以对普通对象进行解构,但要注意 只有构造函数中的命名参数字段支持解构。如下所示,定义了 Person 类:

```dart class Person { final String name; final int age;

Person({ required this.name, required this.age, }); } ```

对象结构语法为:

var 类名( 命名字段1 : 变量1 , 命名字段2 : 变量2, ...) = 对象

dart void foo5(){ Person person = Person(name: 'toly', age: 29); var Person(name : a, age: b) = person; print('======$a====${b}==='); }

同样,如果懒得为变量起名字,也可以直接让字段名称为变量名:

var 类名( : 命名字段1 , : 命名字段2, ...) = 对象

dart void foo5(){ Person person = Person(name: 'toly', age: 29); var Person(:name, :age) = person; print('======$name====${age}==='); }


三、解构时需要注意的问题

1、解构结构的一致性

首先要注意的是,对于 List 、Record、Map 对象来说,左侧的解构结构要和对象数据结构 完全一致。 比如下面列表有三个元素,你只解构了两个,在运行时会报错。我觉得比较坑的是:

如果不一致的话,在 编辑期间 无法发觉,问题只能在运行时暴露,这就或多或少存在一定的代码隐患。

image.png

同理,如果在解构 Map 对象时 key 写错了,在运行时也会报错:

image.png


2、忽略解构单元

List 、Record、Map 对象的解构需要保持结构的一致性,但有时候并不需要完全结构所有的数据,此时可以使用 _ 来忽略对应的结构单元。

dart void foo8() { List<int> numList = [1, 2, 3]; var [first, _,_] = numList; print('====$first===='); }


3、小结

本文从 解构 的角度,认识了一些常用类型的 Pattern 语法,下图是一个小结:

image.png

从这里我们或多或少可以体会出 Patterns 是一种 对模式的匹配。而解构是运用模式匹配的能力,从对象中提取数据为对应变量赋值。我们一开始就说了 Patterns 是一种语法级的特性,解构只是它的作用之一。而且模式也不只是针对于类型,某些运算符也可以作为模式的一部分。

本文简单认识一下 Patterns 的概念和在解构中的应用。另外,在流程控制中和匹配相关的有一个关键字 ---- switch 。下一篇将从 switch 语法的变化,继续了解 Patterns 的作用。谢谢观看 \~

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

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

相关文章

10 缓存双写一致性之更新策略探讨

什么是缓存双写一致性 如果redis中有数据&#xff1a;需要和数据库中的值相同如果redis中无数据&#xff1a;数据库中的值要是最新值 缓存按照操作来分&#xff0c;有细分2种 只读缓存读写缓存 同步直写策略&#xff1a;写缓存时也同步写数据库&#xff0c;缓存和数据库中的…

如何移动下载文件夹到另一个盘?

下载文件夹占用了越来越多的C盘可用空间&#xff1f;本教程将教你如何安全易行地将下载文件夹移动到其他驱动器&#xff0c;以便你可以释放更多的C盘空间。 关于下载文件夹 从网站下载程序后它们会被存储在哪里&#xff1f;一般来说&#xff0c;当你从互联…

基于C++实现的智慧农业移动巡检系统设计(附源码)

Overview 项目源码 https://download.csdn.net/download/DeepLearning_/87863659 此项目开始于2023年2月7日&#xff0c;项目内容为一种AGV图形化操作系统&#xff0c;采用ROS2GO开发&#xff0c;开发环境为Ubuntu18.04、ROS melodic、Qt5.9.9&#xff0c;该项目作为23年挑战杯…

js函数this指向

目录 this的绑定规则  绑定一&#xff1a;默认绑定&#xff1b; ​ 绑定二&#xff1a;隐式绑定&#xff1b; ​ 绑定三&#xff1a;显式绑定&#xff1b; 通过call或者apply绑定this对象  绑定四&#xff1a;new绑定&#xff1b; 内置函数的绑定 this绑定规则的…

给电脑重装系统的时间需要多久才能装好

在进行电脑重装系统时&#xff0c;如果遇到系统安装时间过长的情况&#xff0c;可能会引起用户的困惑和不安。本文将介绍一些常见的原因和解决方法&#xff0c;以帮助您理解并应对系统安装时间过长的情况。 ​工具/原料&#xff1a; 系统版本&#xff1a;Windows 10 专业版 品…

《Java并发编程实战》课程笔记(九)

Semaphore&#xff1a;如何快速实现一个限流器&#xff1f; 信号量模型 信号量模型还是很简单的&#xff0c;可以简单概括为&#xff1a;一个计数器&#xff0c;一个等待队列&#xff0c;三个方法。 在信号量模型里&#xff0c;计数器和等待队列对外是透明的&#xff0c;所以…

chatgpt赋能python:Python图片大小设置的SEO指南

Python 图片大小设置的SEO指南 在网站设计和开发中&#xff0c;图片大小通常是一个重要的问题。合适的图片大小可以极大地影响用户体验和搜索引擎优化&#xff08;SEO&#xff09;结果。Python是一种广泛使用的编程语言&#xff0c;可以用来控制和设置图片大小。在本文中&…

BUUCTF MD5

密文&#xff1a; e00cf25ad42683b3df678c61f42c6bda 简述&#xff1a; 一般MD5值是32位由数字“0-9”和字母“a-f”所组成的字符串&#xff0c;字母大小写统一&#xff1b;如果出现这个范围以外的字符说明这可能是个错误的md5值&#xff0c;就没必要再拿去解密了。 特征&…

SQL-DDL操作数据库、表

SQL-DDL操作数据库、表 1 DDL:操作数据库 1.1 查询数据库 查询所有的数据库 SHOW DATABASES; show databases;1.2 创建数据库 创建数据库 CREATE DATABASE 数据库名称; create database 数据库名称;创建数据库(判断&#xff0c;如果不存在则创建) CREATE DATABASE IF NOT…

SyntaxError:Unexpected end of JSON input while parsing near xxxxx 报错及解决

环境&#xff1a;Node 12.21.0、npm 6.14.11 &#xff08;其他版本也会出现这样的问题&#xff09; 找到报错日志并进行查看&#xff1a; less /Users/roc/.npm/_logs/2023-06-05T02_23_51_747Z-debug.log报错信息如下&#xff1a; 19067 verbose stack SyntaxError: Unexp…

【遇到的问题】JAVA应用程序处于安全原因被阻止。

遇到的问题&#xff1a; 直入正题&#xff0c;远程服务器用JAVA连接KVM报以下错(如图)。 应用程序处于安全原因被阻止 无法验证证书 将不执行该应用程序 名称&#xff1a;Java viewer 发行者&#xff1a;ATEN 位置&#xff1a;https://192.168.210:443 原因&#xff1a; 通过…

vue3实现高德地图多点标注(so easy)

vue3实现高德地图多点标注&#xff08;so easy&#xff09; 前言思路清晰&#xff0c;抽丝剥茧必要的准备工作最简单的部分处理数据之前&#xff08;最关键的思路&#xff09;效果完整代码 前言 非常感谢你能打开这篇博客&#xff0c;我想你一定是遇到了地图多点标注有关的问题…

采购管理系统对企业有什么作用?原来用零代码搭建如此便捷

什么是采购管理系统&#xff1f; 采购管理系统是一种企业内部管理软件&#xff0c;用于协调和管理企业的采购过程。它涵盖了采购计划、询价、比价、采购订单、采购合同、采购收货、发票等一系列采购环节&#xff0c;以及与供应商的信息和交流。其主要目的是&#xff1a;优化采…

M12圆形连接器公母对接带线3PIN4PIN

随着工业自动化的发展&#xff0c;M12圆形连接器公母对接带线3PIN4PIN作为一种重要的连接器件&#xff0c;被广泛应用于各种工业设备中。本文将详细介绍M12连接器的特点以及应用场景&#xff0c;为大家解答M12连接器的相关问题。 M12连接器主要由连接器头、插座和电缆组成&…

【Web网站服务】Nginx Rewrite重写模块

Nginx Rewrite 一、常用的Nginx 正则表达式二、location 匹配的范围2.1location实验 三、rewrite模块3.1rewrite跳转3.2rewrite执行顺3.3flag标记说明3.4rewrite中常用的全局变量3.5rewrite实验3.5.1 基于域名的跳转3.5.2基于客户端IP访问跳转3.5.3基于旧域名跳转到新域名后面加…

三、HAL_无源蜂鸣器的驱动

1、开发环境 (1)KeilMDK&#xff1a;V5.38.0.0 (2)STM32CubeMX&#xff1a;V6.8.1 (3)MCU&#xff1a;STM32F407ZGT6 2、无源蜂鸣器简介 无源蜂鸣器内部没有振荡源&#xff0c;需要采用一定频率的方波才能驱动发声。详情参开以下文章。 八、51单片机之蜂鸣器_51蜂鸣器_朱嘉…

DINO代码学习笔记(三)

DINO代码学习笔记&#xff08;一&#xff09;中已经将输入transformer之前的参数处理给捋了一遍 DINO代码学习笔记&#xff08;二&#xff09;中将encoder部分给捋了一遍 本篇进入decoder&#xff0c;这里先对encoder做一些假设&#xff0c;基于DINO代码学习笔记&#xff08;…

使用Harbor 和 Kraken 优化镜像拉取速

一、P2P镜像分发简述 随着云原生架构被越来越多的企业接受&#xff0c;企业应用中容器集群的规模也越来越大。当容器集群达到一定的规模且单容器应用副本数达到一定级别时&#xff0c;集群中容器镜像的分发将面临挑战。   P2P&#xff08;Peer-to-Peer&#xff0c;点对点&am…

股票策略社群实盘展示

量化策略开发&#xff0c;高质量社群&#xff0c;交易思路分享等相关内容 大家好&#xff0c;我是Le Chiffre 从今年1月份开始&#xff0c;我们开始了松鼠股票策略社群&#xff0c;历经5个月&#xff0c;发布了5个策略。其中有2个多因子&#xff0c;2个etf&#xff0c;1个网格…

一款企业级的供应链采购系统,已开源

介绍 基于pig微服务架构打造 供应链系统&#xff0c;采购配送系统。为客户提供仓储管理、订单管理、打单、货源采购、分拣、配送等系统功能。 软件架构 采用 J2EE 技术体系&#xff0c;基于Spring Cloud微服务框架进行封装&#xff0c;平台设计灵活可扩展、可移植、可应对高…