相对于java,dart代码里经常会遇到一些特殊的操作符号,如级联操作.., 问号相关操作符?, ??, ??=, ?. , 内联 …, …?, 还有 with, mixin…on等。这里对dart中的常用特殊操作符做一些记录
一、级联符号 ..
第一次遇到dart 级联符号(..)实在flutter app的入口函数中,如下:
void main() => runApp(MyApp());
void runApp(Widget app) {
WidgetsFlutterBinding.ensureInitialized()
..scheduleAttachRootWidget(app)
..scheduleWarmUpFrame();
}
.. 是用来连续调用同个类中多个不同方法或变量,有点像java中的链式调用;不同的时Java链式调用需要前面每个方法的返回都是class,而dart的级联..不需要,
new A().B().C().D();
如上面链式调用里,A(),B(),C(),D()都是同一个class A里面的方法,而且至少A(),B(),C()三个方法的返回值都必须是class A,否则无法进行链式调用。
二、with 关键字
- With 可以理解为代码复用,with后面可以跟多个类,跟implements 不同的是,with类里面已经实现了方法, 而implements后面 是abstract类。继承者需要实现implememts类里的所有方法, with则不需要
- 当with后面的类中有相同的方法名时,使用离with 最远类里面的方法
- 当with后面类和extents 后面类有相同方法名时,使用with后面最远类里面的方法
- With 后面必须是object类,即原始类,不是class继承类,否则会报错
“The class xxx can't be used as a mixin because it extends a class other than Object.”
三、Mixin .. on ..
如下是mixin 和 with 一起使用的案例
//ABase
abstract class ABase {
void initInstances() {
print("xxlhome ABase——initInstances");
}
}
//BBase
mixin BBase on ABase{
@override
void initInstances() {
print("xxlhome BBase——initInstances begin");
super.initInstances();
print("xxlhome BBase——initInstances end");
}
}
//CBase
mixin CBase on ABase{
@override
void initInstances() {
print("xxlhome CBase——initInstances begin");
super.initInstances();
print("xxlhome CBase——initInstances end");
}
}
// DBase
mixin DBase on ABase
{
@override
void initInstances() {
print("xxlhome DBase——initInstances begin");
super.initInstances();
print("xxlhome DBase——initInstances end");
}
}
//BaseTest
class BaseTest extends ABase
with BBase, CBase, DBase {
@override
void initInstances() {
print("xxlhome BaseTest——initInstances begin");
super.initInstances();
print("xxlhome BaseTest——initInstances end");
}
I/flutter: xxlhome BaseTest——initInstances beg
I/flutter: xxlhome DBase——initInstances begin
I/flutter: xxlhome CBase——initInstances begin
I/flutter: xxlhome BBase——initInstances begin
I/flutter: xxlhome ABase——initInstances
I/flutter: xxlhome BBase——initInstances end
I/flutter: xxlhome CBase——initInstances end
I/flutter: xxlhome DBase——initInstances end
I/flutter: xxlhome BaseTest——initInstances end
mixin.. on.. 和with配合使用过程自动关联了父子关系,上面代码有点像如下代码
上面代码有点像如下java代码:
class BBase extends ABase{
@override
void initInstances() {
print("xxlhome BBase——initInstances begin");
super.initInstances();
print("xxlhome BBase——initInstances end");
}
}
//CBase
class CBase extends BBase{
@override
void initInstances() {
print("xxlhome CBase——initInstances begin");
super.initInstances();
print("xxlhome CBase——initInstances end");
}
}
// DBase
class DBase extends CBase {
@override
void initInstances() {
print("xxlhome DBase——initInstances begin");
super.initInstances();
print("xxlhome DBase——initInstances end");
}
}
//BaseTest
class BaseTest extends DBase {
@override
void initInstances() {
print("xxlhome BaseTest——initInstances begin");
super.initInstances();
print("xxlhome BaseTest——initInstances end");
}
}
但是minxin 和 with, 配合使用功能更强大,with后面可以跟多个object类, 各个object类更独立,更有利于代码维护,extend只能跟一个类,父子继承关系复杂。
四、dart 中 ? 的用法
除了三目运算符 A?B:C,里面的 ?,dart代码其他地方也可以用 ?
1, 定义变量时用 ?
Element? current = this;
这里表示current可以为空
2. ??
string a = b ?? 'hello';
该代码等价于
if(b == null) {
a = ‘hello’;
}else {
a = b;
}
3, a??=b
该代码等价于
if(a == null) {
a = b;
}
4, c = a?.b();
等价于
if(a == null) {
c = null;
} else {
c = a.b();
}
5, … 和 …?
Dart 2.3 中,引入了上面的2 个符号,用来像数组中插入数据,例如:
- var list = [1, 2, 3];
- // 将 list 中的输入全部插入 list2
- var list2 = [0, ...list];
- assert(list2.length == 4);
为何防止 list 中的数据为 null, 可以使用下面的方式:
- var list;
- var list2 = [0, ...?list];
- assert(list2.length == 1);