- Dart 语言的入口是
main函数,并且必须显式定义。Dart 语言的main函数没有返回值。传递给main函数的命令行参数,是通过List<String>完成的。List是集合类型,每一个String都表示一个参数。 - Dart 语言中打印信息使用
print函数。 - Dart 语言中定义字符串可以使用单引号或双引号。
- Dart 语言中每行代码必须使用分号结尾。
- 编写 Dart 语言创建的文件是
.dart文件。
Dart源码:安装过 Flutter 后,可以在 /Applications/flutter/bin/cache/dart-sdk/lib/core/ 找到 Dart 的源码。
环境搭建

基本语法
main函数是 Dart 入口;- Dart 中打印使用
print;
main 函数的返回值是空 void,在 Dart 中返回值可以省略,由系统自动进行类型判断。
|
|
声明变量
1、明确的声明
- 变量类型 变量名 = 赋值;
|
|
2、类型推导
var 用于定义变量,final、const 用于定义常量。使用他们定义变量或常量时,虽然没有明确指定变量的类型,但是在编译时变量可以明确自己的类型。
使用 var 定义变量:
|
|
使用 final 定义常量:
|
|
使用 const 定义常量:
|
|
final 和 const 的区别:
const在赋值时,赋值的内容必须在编译期间就确定下来。final在赋值时,可以动态获取,如通过计算、函数返回等方式获取一个值,在运行期间来确定一个值。
可以通过函数给 final 赋值:
|
|
final 可以定义两个相同类型的常量。
|
|
const 可以让一个类型只创建一个常量。
|
|
在日常开发中定义常量多使用 final。
可以使用 runtimeType 获取变量当前的类型:
|
|
布尔类型
Dart 中不能判断非零即真,或者非空即真。Bool 类型必须是一个确定的实体。
|
|
字符串类型
Dart 字符串是 UTF-16 编码单元的序列,可以使用单引号或双引号创建一个字符串:
|
|
可以使用三个单引号或者双引号表示多行字符串
|
|
打印结果:
|
|
- 字符串的拼接
字符串和其他变量或表达式拼接时,使用${expression}表达式,如果 expression 是一个标识符,那么 {} 可以省略:
|
|
如果不是一个标识符,则不可以省略 {}:
|
|
数字转字符串:
|
|
字符串转数字:
|
|
集合
1、列表List:[]
|
|
2、集合Set:{}
|
|
3、映射Map
|
|
增删改查
1、列表 List
|
|
2、集合 Set
|
|
3、映射 Map
|
|
函数
基本使用
|
|
sum 函数的参数和返回值都是 int 类型,其中返回值类型可以省略,由 Dart 自动推断:
|
|
- 如果函数中只有一个表达式,可以使用箭头语法(arrow syntax)
=>
|
|
可选参数
在 Dart 中没有函数重载。参数类型分为三类:
- 必选参数;
- 位置可选参数;
- 命名可选参数;
必选参数
|
|
可选参数有两种:
- 位置可选参数:[param1, param2, …];
- 命名可选参数:{param1, param2, …};
命名可选参数
- 命名可选参数:{param1, param2, …};
位置不确定,但是形参必须要写。
|
|
位置可选参数
- 位置可选参数:[param1, param2, …];
不需要写名形参,实参和形参在进行匹配时,是根据位置的匹配。
|
|
参数默认值
在不传参数的情况下,使用默认值。
|
|
函数是一等公民
函数作为一等公民,即可以赋值给一个变量,也可以作为另一个函数的参数或这返回值。
1、将函数赋值给一个变量:
|
|
可以看到 hello 是一个 Closure: (String) => dynamic 的类型的函数。
2、将函数作为另一个函数的参数:
|
|
3、将函数作为另一个函数的返回值:
|
|
4、自定义函数类型
|
|
匿名函数
匿名闭包(anonymous function),也叫作 lambda 或 闭包(closure)。定义一个没有名字的函数,作为函数的参数或返回值,提高编码效率。
|
|
say 函数的返回值为 void,参数是一个函数,该函数的参数是 String 类型,函数体是一个打印方法:
|
|
示例二:使用 forEach 遍历
|
|
打印结果:
|
|
词法作用域
优先使用自己作用域中的变量,如果没有找到,则一层层向外查找。
|
|
|
|
|
|
词法闭包
|
|
创建出来的 adder 记住了创建时传入的 2。
隐式返回
所有函数都有一个返回值。如果没有指定返回值,则默认返回 null。
|
|
特殊运算符
??空值合并运算符
|
|
??=空值赋值运算符
|
|
..级联运算符
|
|
打印信息:
|
|
for循环
|
|
for-in循环
|
|
Dart之面向对象
类的定义
|
|
1、初始化类时,类名前的 new 可以省略:
|
|
2、Dart 语言要求类的成员变量,在类初始化前要有确定的值。如果没有在初始化时给成员变量赋值,就会报错:

类的构造函数
|
|
使用 json 初始化类:
|
|
初始化列表
- 初始化列表会在构造函数前执行,常用于设置
final变量的值,使用逗号,分隔初始化表达式。
|
|
在创建对象时,可以选择传或不传 age,不传使用默认值:
|
|
Dart 3.0 后,使用 ? 表示 age 可能为 null,在可选参数列表中使用 ?? 判断 age 是否有值。

widget 中 container 的相关源码(路径/Applications/flutter/packages/flutter/lib/src/widgets/container.dart):
|
|
重定向构造方法
因为 Dart 不支持方法重载,所以对于有多个成员变量的类,不能写多个不同的构造方法:

可以使用构造函数重定向来实现这种场景:
|
|
工厂构造方法
普通的构造函数会自动返回创建出来的对象,不能手动返回:
|
|
工厂构造函数最大的特点是可以手动返回一个对象:
|
|
📢注意:这里的 _nameCache[name]! 加了 !,表明一定不为 null。这是 Dart 3.0 增加的能力-空安全类型系统。
setter 和 getter
|
|
类的继承
- 使用
extends表示继承关系; - 子类的构造方法在执行前,将隐含调用父类的无参默认构造方法(没有参数且与类同名的构造方法)。
- 如果父类没有无参默认构造方法,则子类的构造方法必须在初始化列表中通过
super显式调用父类的某个构造方法。
|
|
Object 和 dynamic 的区别
Dart 中所有类型都是 Object 的子类,包括 Function 和 Null。
- dynamic 与 Object 声明的变量都可以赋值任意对象,且后期可以改变赋值的类型。

Object 对象使用的属性和方法若不存在,编译时会报错。
dynamic 对象使用的属性和方法若不存在,编译时不会报错,运行时会报错。

抽象类的使用
📢注意一:继承自抽象类后,必须实现抽象类中没有实现的方法。

📢注意二:抽象类不能实例化。

必须实现抽象类中没有实现的方法:
|
|
可以重写抽象类中有实现的方法:
|
|
隐式接口
Dart 默认情况下所有的类都是隐式接口。在将一个类作为接口使用时,实现接口的类,必须实现这个接口中所有方法。通常将用于给别人实现的类声明为抽象类。
定义一个 Tom 类,继承自 Person,使用 Run、Swim 类作为接口:
|
|

通过 implements 实现某个类时,必须重新实现类定义的所有方法(无论这个类是否已经对方法实现)。如果想要直接复用之前类的原有实现方案,则可以使用 mixin混入。
mixin混入的使用
想要直接复用之前类的原有实现方案,一般采取继承。但是因为 Dart 只支持单继承,所以无法直接复用多个类原有的实现方案。
想要直接复用多个类原有的实现方案,可以采用 Mixin 混入的方式:
- 使用
mixin关键字定义一个类; - 使用
with关键字来实现混入;
|
|
如果要类比的话,mixin 混入和 Swift 的协议有异曲同工之妙。
implements 和 with 关键字一起使用时,implements 要放最后:
|
|
类属性
|
|
类方法
|
|
枚举
选择器必须覆盖枚举类型的全部情况,否则会报错:

|
|
Dart中库的使用
一、使用系统库
使用 import '库的url' 的形式导入一个库。
|
|
库url有三种方式:
1、使用 dart: 表示 dart 标准库,
|
|
2、使用相对路径,导入项目中自定义的 .dart 文件:
|
|
3、Pub包管理系统中的库,使用前缀 package::
|
|
二、使用自定义库

1、as 关键字给库起别名。
当各个库有命名冲突的时候,可以使用 as 关键字来使用命名空间:
|
|
2、默认情况下,导入一个库时就是导入这个库中所有的内容。
show:执行要导入的内容。
|
|
hide:隐藏某个要导入的内容,导入其它内容。
|
|
3、将需要导入的库,使用 export 抽取到公共的 dart 文件

|
|
使用第三方库
|
|
参考 http 1.1.0