Dart 3.0 语法新特性

您所在的位置:网站首页 正则表达式基本语法是什么 Dart 3.0 语法新特性

Dart 3.0 语法新特性

#Dart 3.0 语法新特性 | 来源: 网络整理| 查看: 265

一、 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 三种类型,有着非常明显的结构特征:

记录 Record 类型 |--- 普通值 (v1, v2 ,...) |--- 命名值 (k1:v1,k2:v2 ,...) 列表 List 类型 |--- 值列表 [v1,v2,...] 映射 Map 类型 |--- 键值对 {k1:v1, k2:v2 ,...} 二、 Patterns 的解构能力

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

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

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

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

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

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

Record 的解构语法是 :

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

命名 Record 类型

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

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 变量赋值。

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 对象

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

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

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

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

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

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 类:

class Person { final String name; final int age; Person({ required this.name, required this.age, }); }

对象结构语法为:

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

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

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

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

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 对象的解构需要保持结构的一致性,但有时候并不需要完全结构所有的数据,此时可以使用 _ 来忽略对应的结构单元。

void foo8() { List numList = [1, 2, 3]; var [first, _,_] = numList; print('====$first===='); } 3、小结

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

image.png

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

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



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3