Dart概览与基础

Dart语言其实早在2011年 Google就发布了该语言。Dart的诞生最早是要解决 JavaScript 存在的、在语言本质上无法改进的缺陷。Dart在最初的定位是运行在浏览器中的脚本语言。

Dart都有哪些特性呢?

  1. Dart同时支持JIT和AOT的语言之一,这使得在开发调试时效率得到很大提升。
  2. Dart VM的内存分配策略比较简单,创建对象时只需要在堆上移动指针,内存增长始终是线性的,省去了查找可用内存的过程。在 Dart 中,并发是通过 Isolate 实现的。Isolate 是类似于线程但不共享内存,独立运行的 worker。这样的机制,就可以让 Dart 实现无锁的快速分配。Dart 的垃圾回收,则是采用了多生代算法。新生代在回收内存时采用“半空间”机制,触发垃圾回收时,Dart 会将当前半空间中的“活跃”对象拷贝到备用空间,然后整体释放当前空间的所有内存。回收过程中,Dart 只需要操作少量的“活跃”对象,没有引用的大量“死亡”对象则被忽略,这样的回收机制很适合 Flutter 框架中大量 Widget 销毁重建的场景.
  3. Dart中没有线程,只有Isolate。Isolate之间不会共享内存,通过事件循环在事件队列上传递消息通信。相比支持并发线程的高级语言,就能够避免由于抢占资源加锁带来的性能损耗甚至是死锁的严重问题。 单线程模型后面会详细介绍。

Dart的特性介绍完了,我们来看看Dart语言的相关基础

从“hello world”开始,体验下Dart

printInteger(int a) {
  print('Hello world, this is $a.'); 
}

main() {
  var number = 2019; 
  printInteger(number); 
}

Dart 跟大多数语言一样,要求以main函数作为执行的入口的,运行结果:

Hello world, this is 2019. 

Dart的类型与变量

在 Dart 中,我们可以用 var 或者具体的类型来声明一个变量。当使用 var 定义变量时,表示类型是交由编译器推断决定的,当然你也可以用静态类型去定义变量,更清楚地跟编译器表达你的意图,这样编辑器和编译器就能使用这些静态类型,向你提供代码补全或编译警告的提示了。在默认情况下,未初始化的变量的值都是 null,因此我们不用担心无法判定一个传递过来的、未定义变量到底是 undefined,还是烫烫烫而写一堆冗长的判断语句了。Dart 是类型安全的语言,并且所有类型都是对象类型,都继承自顶层类型 Object,因此一切变量的值都是类的实例(即对象),甚至数字、布尔值、函数和 null 也都是继承自 Object 的对象。也就是说 如果我们在声明一个变量没有赋值的情况下该变量都是null。数据类型的使用声明跟其他语言基本一致,这里就不赘述了。需要说明的是dart内的num类型只有两种子类:即 64 位 int 和符合 IEEE 754 标准的 64 位 double。前者代表整数类型,而后者则是浮点数的抽象。

常量定义

如果你想定义不可变的变量,则需要在定义变量前加上 final 或 const 关键字:const,表示变量在编译期间即能确定的值;
final 则不太一样,用它定义的变量可以在运行时确定值,而一旦确定后就不可再变。
对于流程控制语法:如 if-else、for、while、do-while、break/continue、switch-case、assert跟其他语言类似,可以到dart官网或者使用过程中慢慢学习。

函数

在 Dart 中,所有类型都是对象类型,函数也是对象,它的类型叫作 Function。这意味着函数也可以被定义为变量,甚至可以被定义为参数传递给另一个函数。
下面这段代码示例我们来感受下:

bool isZero(int number) { //判断是否为0 由于函数方法体只有一行,我们也可以写成
// bool isZero(int number) => number==0;
  return number == 0; 
}

void printInfo(int number,Function check) { //用check函数来判断整数是否为0
  print("$number is Zero: ${check(number)}");
}
Function f = isZero;
int x = 10;
int y = 0;
printInfo(x,f);  // 输出 10 is Zero: false
printInfo(y,f);  // 输出 0 is Zero: true

在这里我们定义了printInfo函数,和isZero函数,我们将isZero函数传给printInfo函数,完成判断整数是否为0的打印。
在面向对象的开发中 都提供了函数的重载,那么Dart中是如何实现函数重载的呢?其实Dart 认为重载会导致混乱,因此从设计之初就不支持重载,而是提供了可选命名参数和可选参数。具体的方式:
1、给参数增加{},以 paramName: value 的方式指定调用参数,也就是可选命名参数;
2、给参数增加[],则意味着这些参数是可以忽略的,也就是可选参数。
在使用这两种方式定义函数时,我们还可以在参数未传递时设置默认值。
在 Flutter 中会大量用到可选命名参数的方式,通过个例子感受下:

void main() {
  printInfoOne(name: "张三", sex: "男"); // 张三,男
  printInfoTwo("张三", "男"); // 张三,男
  printInfoOne(name: "张三"); // 张三,女
  printInfoTwo("张三"); // 张三,女
}

void printInfoOne({String name, String sex = "女"}) => print("$name,$sex");

void printInfoTwo(String name, [String sex = "女"]) => print("$name,$sex");

类的声明跟其他语言一样使用class关键字。需要说明的是在dart中没有public、protected、private 这些关键字,我们只要在声明变量与方法时,在前面加上“”即可作为 private 方法使用。如果不加“”,则默认为 public。不过,“_”的限制范围并不是类访问级别的,而是库访问级别。
在类的构造函数语法糖进行初始化

String name;
String sex;
class Person(this.name,this.sex);

继承

在面向对象的编程语言中,将其他类的变量与方法纳入本类中进行复用的方式一般有两种:继承父类和接口实现。当然,在 Dart 也不例外。这里对继承就不过多阐述了。
下面通过个例子来说明下Dart中的继承与接口的差别


class Point {
  num x = 0, y = 0;
  void printInfo() => print('($x,$y)');
}

//PointOne继承自Point
class PointOne extends Point{
  num z = 0;
  @override
  void printInfo() => print('($x,$y,$z)'); //覆写了printInfo实现
}

//PointTwo是对Point的接口实现
class PointTwo implements Point {
  num x = 0, y = 0; //成员变量需要重新声明
  void printInfo() => print('($x,$y)'); //成员函数需要重新声明实现
}

var xxx = PointOne(); 
xxx
  ..x = 1
  ..y = 2
  ..z = 3; //级联运算符,等同于xxx.x=1; xxx.y=2;xxx.z=3;
xxx.printInfo(); //输出(1,2,3)

var yyy = PointTwo();
yyy
  ..x = 1
  ..y = 2; //级联运算符,等同于yyy.x=1; yyy.y=2;
yyy.printInfo(); //输出(1,2)
print (yyy is Point); //true
print(yyy is PointTwo); //true

可以看出,子类 PointTwo 采用接口实现的方式,仅仅是获取到了父类 Point 的一个“空壳子”,只能从语义层面当成接口 Point 来用,但并不能复用 Point 的原有实现。那么,我们是否能够找到方法去复用 Point 的对应方法实现呢?
除了继承和接口实现之外,Dart 还提供了另一种机制来实现类的复用,即“混入”(Mixin)。混入鼓励代码重用,可以被视为具有实现方法的接口。这样一来,不仅可以解决 Dart 缺少对多重继承的支持问题,还能够避免由于多重继承可能导致的继承歧义,无法明确调用的方法是哪个父类的方法。
要使用混入,只需要 with 关键字即可

class PointTwo with Point {
}

var yyy = PointTwo();
print (yyy is Point); //true
print(yyy is PointTwo); //true

Mixin会在后面着重分析,为什么混入的方式可以避免继承歧义。

运算符

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

class Point {
  num x, y;
  Point(this.x, this.y);
  // 自定义相加运算符,实现向量相加
  Point operator +(Point v) =>  Point(x + v.x, y + v.y);
  // 覆写相等运算符,判断向量相等
  bool operator == (dynamic v) => x == v.x && y == v.y;
}

final x = Point(3, 3);
final y = Point(2, 2);
final z = Point(1, 1);
print(x == (y + z)); //  输出true

operator 是 Dart 的关键字,与运算符一起使用,表示一个类成员运算符函数。在理解时,我们应该把 operator 和运算符作为整体,看作是一个成员函数名。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容