Dart语言学习笔记一-概览

此篇内容均来源于《Dart编程语言》--[美]Gilad Bracha 著 戴虬 译
设计准则 1.1 万物皆对象 dart是一门由google开发并被批准为ECMA标准(ECMA-408)的通用编程语言。它可以用于构建web端、服务端和移动端应用程序。它是开源的,使用宽松的免费软件许可证(修改版BSD许可证)。Dart是完全面向对象的,使用类和单继承,可编译为JavaScript,语法风格是类C的。它支持接口、mixin、抽象类、泛型和可选类型。
Dart是一门纯面向对象的编程语言,这意味着Dart程序在运行时所处理的值都是对象,甚至包括数字,布尔值等基本数据,无一例外。
Dart坚持对所有数据统一处理,这方便了所有与语言相关的人员:语言的设计者,实现者,以及最重要的使用者。
1.2 面向接口编程,而非面向实现 关注对象的行为而非他的内部实现,这是面向对象编程语言的核心原则。虽然实现的不够完美,Dart却力图通过以下几种方式来维护这个原则。
  • Dart的类型基于接口,而不是类。作为一项原则,任意类都隐含了一个接口,能够被其它类实现,不管其他类是否使用了同样的底层实现(部分core type例外,比如数字,布尔值与字符串)
  • Dart没有final方法,允许重写几乎所有方法(同样,部分内置的操作符例外)。
  • Dart把对象进行了抽象封装,确保所有外部操作都通过存取方法来改变对象的状态
  • Dart的构造函数允许对对象进行缓存,或者从子类型创建实例,因此使用构造函数并不意味着绑定了一个具体的实现。
1.3 类型可选
  • 类型在语法层面上来说是可选的
  • 类型对运行时语义没有影响
    类型可选照顾了那些不愿意与类型系统打交道的开发者。因此而选择Dart的开发者,完全可以把Dart当成一门动态类型语言。虽然类型可选,但只要代码中有类型注解,就意味着代码有了额外的文档,所有的编码人员都会从中受益。类型注解同时让工具能更好的配合开发者的开发工作。
对于可能存在的类型不一致和遗漏,Dart会给出警告,不会报错。这些警告的程度和性质都经过校准,不会铺天盖地的出现,确保真正对开发者有益。同时,Dart编译器不会拒绝一段缺少类型或类型不一致的程序。
概述 2.1最简单的表达式
3

这个表达式的值是整数3.
mymain(){ print("hello world"); print(3); print(3+4); print((3+4)*6); print(1+2*2); print(1234567890987654321*1234567890987654321); } 结果: hello world 3 7 42 5 6172041164457194081 Exited

最后一个例子比较有趣, 书上的结果是1524157877457704723228166437789971041.Dart中的整数很像数学里的数字,他们没有32位或64位可代表的最大值的限制,其大小的唯一限制是可用内存。
Dart不仅支持整数,也支持浮点数,字符串,布尔值,许多内置类型都有很简便的语法
dataType() { 3.14159; // 一个浮点数 'a string'; true; false; //布尔值 []; //一个空列表 [ 0, 1.0, false, 'a', [2, 2.0, true, "b"] ]; // 有5个元素的列表 ,最后一个也是列表。 }

Dart的列表相当于其他语言的数组,Dart是用List来表示数组的。
list(){ print([1,2,3].length); // 3 print([].length); // 0 print([].isEmpty); // true print(['a'].isNotEmpty); // true }

2.2 函数 一个Dart程序的执行总是开始于对main() 函数的调用。每个函数都由函数头与函数体组成。函数的头部定义了函数的名称与参数。
twice(x) => x * 2;

声明了一个名为twice的函数,并有一个名为x的参数。该函数返回x乘以2的结果。我们可以这样来执行它
twice(2); // 4

以上函数调用的结果是4.这个twice函数有两部分,一部分是由函数名与形式参数组成的函数签名,另一部分就是跟在=>后面的只包含了一个表达式的函数体。另一种更传统的书写方式是:
twice(x) { return x * 2; }

另一个函数
// 使用了if语句 max(x, y) { if (x > y) return x; else return y; }

可以简写成
// 使用条件表达式 max(x, y) => (x > y) ? x : y;

另一个更加复杂的函数
maxElement(a) {// 接收一个列表a,并返回一个最大值 var currentMax =// 声明一个currentMax变量,并对其进行初始化(Dart程序中每个变量必须显示声明) a.isEmpty ? throw 'Maximal element undefined for empty arrray' : a[0]; // 异常是使用throw语句抛出的。throw关键字后面跟着一个定义抛出内容的表达式。在Dart中, // 任何类型值都可以被抛出,不要求他们是特定的Exception类型。 for (var i = 0; i < a.length; i++) { currentMax = max(a[i], currentMax); } return currentMax; }

2.3 类 Dart允许你在类外部定义函数与变量。虽然如此,Dart是一门纯面向对象的语言。我们前面看到的所有值,包括数字, 字符串,布尔值,列表甚至函数本身都是Dart中的对象。所有这些对象都是某个类的实例。像length,isEmpty这些操作, 甚至[]索引操作符,都是对象的方法。
现在我们学习如何编写一个类。请看这个Point类,它代表了直角坐标系的点:
class Point { var x, y; Point(a, b) { x = a; y = b; } }

要创建一个Point类的实例,我们可以用new表达式来调用它的构造函数:
var origin = new Point(0, 0); var aPoint = new Point(3, 4); var anotherPoint = new Point(3, 4);

【Dart语言学习笔记一-概览】以上3行创建了3个新的不一样的Point实例,特别是,aPoint和anotherPoint是两个不同的对象。每个对象都有唯一标识,他们通过这个标识来区分彼此。
每个Point的实例都有各自的x和y变量的副本,可以通过点符号来访问他们:
printPoint(){ print(origin.x); print(origin.y); print(aPoint.x); print(aPoint.y); print(anotherPoint.x); print(anotherPoint.y); } 结果如下: 0 0 3 4 3 4

变量x和y的值是由构造函数的实际参数来设置的,而构造函数是由new调用的。将构造函数的形式参数直接赋值给同名的字段,这种方式非常普遍,所以Dart为此提供了一种特殊的语法糖:
class Point{ var x, y; Point(this.x, this.y); }

新版的Point与原版完全相同,但更简洁。我们再给它添加一些行为:
class Point{ var x, y; Point(this.x, this.y); scale(factor) => new Point(x * factor, y * factor); }

这个版本多一个scale方法,它接收一个定义比例系数的参数factor,并返回一个新的点。新的点的坐标是根据当前点的坐标按照facor缩放而得来的。
print(aPoint.scale(2).x); // 6 print(anotherPoint.scale(3).y); // 12

另外一个有趣的操作就是对点进行加法操作:
class Point{ var x, y; Point(this.x, this.y); scale(factor) => new Point(x * factor, y * factor); operator + (p) => new Point(x + p.x, y + p.y); } 结果: print((aPoint + anotherPoint).y); // 8

2.4 静态成员 Dart也支持静态成员。我们可以给Point添加一个计算两点间距离的静态方法
static distance(p1, p2) { var dx = p1.x - p2.x; var dy = p1.y - p2.y; return sqrt(dx * dx + dy * dy); }

static修饰符表明此方法不针对某个特定实例,它无法访问实例变量x和y,因为实例变量对于每个Point实例都是不同的。
Dart代码用库作为模块化的基本单元。每个库都定义了一个的命名空间,这个命名空间包含所有在库中声明的实体的名称,其他库的实体也能被导入进来。Dart核心库中声明的实体,都会被隐含的导入到所有的Dart库中。
import 'dart:math'; class Point { var x, y; Point(this.x, this.y); scale(factor) => new Point(x * factor, y * factor); operator +(p) => new Point(x + p.x, y + p.y); static distance(p1, p2) { var dx = p1.x - p2.x; var dy = p1.y - p2.y; return sqrt(dx * dx + dy * dy); } }

    推荐阅读