Dart语法实践

Posted by JamesPxy on 2019-11-11

Dart在线coding网站:

Map List

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void main() {

var arr1 = <String>['Tom', 'Andy', 'Jack'];
var arr2 = new List<int>.of([1,2,3]);
arr2.add(499);
arr2.forEach((v) => print('${v}'));
print(arr2 is List<int>); // true

var map1 = <String, String>{'name': 'Tom','sex': 'male',};
var map2 = new Map<String, String>();
map2['name'] = 'Tom';
map2['sex'] = 'male';
map2.forEach((k,v) => print('${k}: ${v}'));
print(map2 is Map<String, String>); // true
}

Dart 可选命名参数和可选参数

有时,一个函数中可能需要传递多个参数。那么,如何让这类函数的参数声明变得更加优雅、可维护,同时降低调用者的使用成本呢?C++ 与 Java 的做法是,提供函数的重载,即提供同名但参数不同的函数。
但 Dart 认为重载会导致混乱,因此从设计之初就不支持重载,而是提供了可选命名参数和可选参数。

具体方式是,在声明函数时:给参数增加{},以 paramName: value 的方式指定调用参数,
也就是可选命名参数;给参数增加 [],则意味着这些参数是可以忽略的,也就是可选参数。
在使用这两种方式定义函数时,我们还可以在参数未传递时设置默认值。我以一个只有两个参数的简单函数为例,来和你说明这两种方式的具体用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//要达到可选命名参数的用法,那就在定义函数的时候给参数加上 {}
void enable1Flags({bool bold, bool hidden}) => print("$bold , $hidden");

//定义可选命名参数时增加默认值
void enable2Flags({bool bold = true, bool hidden = false}) => print("$bold ,$hidden");

//可忽略的参数在函数定义时用[]符号指定
void enable3Flags(bool bold, [bool hidden]) => print("$bold ,$hidden");

//定义可忽略参数时增加默认值
void enable4Flags(bool bold, [bool hidden = false]) => print("$bold ,$hidden");

//可选命名参数函数调用
enable1Flags(bold: true, hidden: false); //true, false
enable1Flags(bold: true); //true, null
enable2Flags(bold: false); //false, false

//可忽略参数函数调用
enable3Flags(true, false); //true, false
enable3Flags(true,); //true, null
enable4Flags(true); //true, false
enable4Flags(true,true); // true, true

运算符

运算符Dart 和绝大部分编程语言的运算符一样,所以你可以用熟悉的方式去执行程序代码运算。不过,Dart 多了几个额外的运算符,用于简化处理变量实例缺失(即 null)的情况。

  • ?. 运算符:假设 Point 类有 printInfo() 方法,p 是 Point 的一个可能为 null 的实例。那么,p 调用成员方法的安全代码,可以简化为 p?.printInfo() ,表示 p 为 null 的时候跳过,避免抛出异常。
  • ??= 运算符:如果 a 为 null,则给 a 赋值 value,否则跳过。这种用默认值兜底的赋值语句在 Dart 中我们可以用 a ??= value 表示。
  • ?? 运算符:如果 a 不为 null,返回 a 的值,否则返回 b。在 Java 或者 C++ 中,我们需要通过三元表达式 (a != null)? a : b 来实现这种情况。而在 Dart 中,这类代码可以简化为 a ?? b。

Dart核心特性实践

可选参数,with多继承,重载运算符等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
class Meta {
double price;
String name;
// 成员变量初始化语法糖
Meta(this.name, this.price);
}

abstract class PrintHelper {
printInfo() => print(getInfo());
getInfo();
}

class Item extends Meta with PrintHelper {
int count;
Item(name, price, {int count = 1}): super(name, price) {
this.count = count;
}
// 重载 + 运算符,将商品对象合并为套餐商品
Item operator+(Item item) => Item(name + item.name, price + item.price);
@override
getInfo() => '''
商品名: $name
单价: $price
数量: $count
---------------
''';
}

//with 表示以非继承的方式复用了另一个类的成员变量及函数
class ShoppingCart extends Meta with PrintHelper{
DateTime date;
String code;
List<Item> bookings;
// 以归纳合并方式求和
double get price => bookings.reduce((value, element) => value + element).price;
// 默认初始化函数,转发至 withCode 函数
ShoppingCart({name}) : this.withCode(name:name, code:null);
//withCode 初始化方法,使用语法糖和初始化列表进行赋值,并调用父类初始化方法
ShoppingCart.withCode({name, this.code}) : date = DateTime.now(), super(name,0);

getBookingInfo() {
String str = "";
for (Item item in bookings) {
str += item.getInfo();
}
return str;
}

//?? 运算符表示为 code 不为 null,则用原值,否则使用默认值 " 没有 "
@override
getInfo() => '''
购物车信息:
-----------------------------
商品列表:
---------------
${ getBookingInfo() }
用户名: $name
优惠码: ${code??" 没有 "}
总价: $price
Date: $date
-----------------------------
''';
}

void main() {
ShoppingCart.withCode(name:'张三', code:'123456')
..bookings = [Item('苹果',10.0, count: 10), Item('鸭梨',20.0, count: 5)]
..printInfo();

ShoppingCart(name:'李四')
..bookings = [Item('香蕉',15.0), Item('西瓜',40.0)]
..printInfo();
}

极客时间专栏《Flutter核心技术与实战》的全部代码示例:

https://github.com/cyndibaby905/flutter_core_demo



支付宝打赏 微信打赏

赞赏一下