一、 介绍
1. Dart致力于打造漂亮且高质量的跨屏体验
1.1 针对客户端开发优化
1.2 丰富且强大的框架
1.3 令人愉悦且灵活的工具
2.安装
2.1 一般跟随框架安装,如flutter
2.2 可通过DartPad在线编写和运行代码
2.3 官网:www.dartlang.org
DartPad地址: dartpad.dartlang.org
二、Hello Dart
main(){
var name = 'Dart';
print('Hello $name');
}
三、重要概念
- 一切变量都是对象,包括数字、函数和null
- 对象是类的实例,所有类都继承于Object
- 强类型但支持类型推断
- 如果不想指定具体类型可以用dynamic
- 支持泛型,比如List<int>或List<dynamic>
- 支持顶层函数,类方法,实例方法和嵌套函数
- 支持顶层变量、类变量、实例方法和局部变量
- 以下划线_打头的变量为私有,只能在库内部使用
- 标识符只能以字母或下划线打头,后面跟任意多个字母、数字或下划线字符
- 表达式在运行时可以求值,而语句不行
- 代码问题分为warning和error两种
12.error分为编译时错误和运行时错误两种,运行时错误会导致抛出异常
四、变量
- 变量类型可自动推断,或者显示指定
- 未初始化的变量值都是null,包括数字
- 如果某个变量的值在定义后不会再改变,那就声明为final或const
- final和const变量只能赋值一次,但const变量的值需要在编译时就能确定
- final和const 变量必须在定义的时候就完成初始化
- const变量的值须为编译时常量,包括数字和字符串字面量、其他常量或算术运算结果
- const 除了用来声明变量,也可用来声明值,也就是常值
- 初始化const变量时可以省去值前面的const,因为const变量的值肯定得是一个常值
- 常值用来防止内容变化,常量用来避免变量寻址,final变量用来提升代码的安全性
五、内置类型
- 数字(num)
1.1 num是int和double的基类
1.2 int 为64位整数,double为64位浮点数 - 字符串(String)
2.1 字符串是UTF-64码元序列,每个Unicode字符映射为1个或2个码元
2.2 字符串字面量可以使用单引号或双引号
2.3 使用${expression}来插入变量值,如果expression是个合法的标识符,则可以省去{}
2.4 使用毗连字符串常量或者+操作符来拼接字符串
2.5 使用三重引号来定义多行字符串
2.6 使用r前缀来声明原始字符串,其内不做字符转义
2.7 只要内部插入的表达式为编译时常量,则字符串字面量为编译时常量 - 布尔(bool)
3.1 只有两个值true和false,都是编译时常量
3.2 在需要布尔类型的地方必须使用布尔值 - 列表(List)
4.1 列表就是其他语言里的数组,用来表示对象序列
4.2 列表索引序号从0开始,知道list.length - 1
4.3 在列表字面量前使用const 来声明常量
4.4 使用[]操作符来操作列表元素 - 哈希表(Map)
5.1 哈希表用来关联键和值,键和值可以是任意类型的对象,但键必须唯一
5.2 使用[]操作符来操作哈希表的值
5.3 在哈希表字面量前使用const 来声明常值 - 符文(Rune)
6.1 Rune 是由UTF-32码点组成的字符串,一个Rune字符对应一个Unicode字符
6.2 码点一般使用4个十六进制字符\uXXXX来表示,如果超过4个,则需要使用{}将十六进制字符括起来
6.3 字符串和Rune直接可互相转换
六、函数
- 函数也是一种对象,类型为Function
- 函数参数和返回值类型可省略,以支持动态类型
- 如果函数体只包含一个表达式,可使用箭头语法来定义
- 可选参数
4.1 可选命名参数使用{}来指定,并且可使用注解@required 标注为必需
4.2 可选位置参数使用[]来指定
4.3 可选参数默认值使用=来指定,如未制定则默认值为null - 每个程序都应有个位于顶层的main函数,它是程序入口
- 函数可作为函数参数值,也可赋值给变量
- 可定义匿名函数,一般作为函数参数值或赋值给变量
- 变量作用域静态确定,也就是同代码布局,每对大括号定义一个作用域,嵌套大括号定义嵌套作用域
- 闭包是一个能访问其外层作用域变量的函数,即便该函数在其他地方被调用
- 如果函数没有指定返回值,则默认返回null,如果确实不想返回任何值,则可指定返回类型为void
七、操作符
- 操作符有优先级,从高到低为一元后缀、一元前缀、乘除、加减、移位、位运算、关系运算和类型测试、相等性运算、逻辑运算、null判断、三元表达式、级联调用和赋值
- 在优先级判断比较模糊的地方,使用()来提升可读性
- 算术运算
3.1 +、-、*、/、-expr、~/(整除)、%(求余)
3.2 ++var、var++、--var、var-- - 相等性和关系运算
4.1 ==、!=、>、<、>=、<=
4.2 ==判断值是否相等,如果要判断是否为同一个对象,使用identical() - 类型测试
as、is、is! - 赋值
6.1 =、??=(null赋值,只有为null的时候才进行赋值,如果不为null,则不进行赋值操作)
6.2 -=、/=、%=、>>=、^=、+=、*=、~/=、<<=、&=、|= - 逻辑运算
!expr、||、&&
8、位运算
&、|、^、~expr(按位取反)、<<、>> - 条件表达式
9.1 三元表达式 condition?expr1:expr2
9.2 null判断 expr1??expr2 (expr1为null则取expr2的值) - 级联调用.. 方法调用的时候一般是用一个. 当我们需要对一个对象执行一系列操作时,级联是非常有用的,方便我们操作对象,节省代码量,示例如下:
var sortedColors =
['red', 'green', 'orange', 'blue', 'black', 'pink'].sublist(1, 4).sort();
print(sortedColors);
//在编辑器中代码出错,sortedColors是null
var colors =
['red', 'green', 'orange', 'blue', 'black', 'pink'].sublist(1, 4);
colors.sort();
print(colors);
var sortedColors1 =
['red', 'green', 'orange', 'blue', 'black', 'pink'].sublist(1, 4)..sort();
print(sortedColors1);
}
- 函数调用()
- 下标访问[]
- 成员访问.
- 条件式成员访问 ?.
八、控制流程语句
- if-else
条件必须为布尔值 - for loop
2.1 循环内的闭包会捕获循环变量的当前值
2.2 可迭代对象可使用for-in来迭代其内部元素 - while and do-while
while先判断条件,满足后执行循环体,do-while 先执行循环体,再进行判断 - break and continue
break 终止循环,continue跳过本次循环剩余代码,直接进入下一次循环 - switch-case
5.1 使用==操作符来比较整数、字符串或编译时常量,包括枚举类型
5.2 非空case语句正常情况下应以break结束,也可使用continue、throw或return来结束
5.3 使用default语句来匹配其他情况
5.4 空case语句会落入下方case语句
5.5 可结合使用continue和label来跳转到其它case语句
5.6 一般用于解释器和扫描器,编写应用时尽量少用 - assert
6.1 只在开发模式下有效,生产模式下会被忽略
6.2 条件判断失败时会抛出AssertionError异常,可通过第二个参数指定错误信息
九、异常
- 异常表示有一些预料之外的错误发生了
- 如果异常未被捕捉,则程序将终止运行
- Dart内置了Exception和Error两种类型,前者用于核心库异常,后者用于应用代码异常
- 可使用throw抛出任何非null对象作为异常
- throw语句是一个表达式
- 使用try-catch语句来捕捉异常,以防止异常扩散,同时可使用on语句来处理特定类型的异常
- 使用rethrow来再次抛出异常
- 使用finally语句来执行无论是否出现异常都要运行的代码