Dart语言特性
Dart语言特性
变量声明
var可以接收任何类型的变量,一旦赋值,就不能改变其变量类型
1 | var a = 100; |
dynamic和Object
*Object是所有对象的基类,所有类型都是Object的子类,包括函数(Function)和Null, 所以任何类型的数据都可以赋值给Object声明的对象。
*dynamic和var一样,也可以接收任何类型的变量
* 注意:dynamic和Object赋值后,后期可以改变其变量类型final和const
* 被final和const修饰的变量,变量类型可以省略
*const是编译时常量,而final是在第一次使用时,被赋值
数据类型
- 数值类型
| 变量关键字 | 说明 |
|---|---|
int |
整数类型 |
double |
浮点类型 |
1 | void main() { |
- 字符串类型
1 | void main() { |
- 布尔类型
1 | void main() { |
- 数组类型
1 | void main() { |
- 字典类型
1 | void main() { |
函数
Dart是一种真正的面向对象的语言,所以函数(Function)也是对象。因此函数可以作为参数传递给其他函数或者赋值给变量。
- 函数没有显式返回值时,默认返回dynamic类型。例如
1
2
3bool isToday(long mills) {
} - 函数返回值没有类型推断
- 对于只包含一个函数的表达式,可以是用简写方式
bool isNumOne => number == 1;
函数作为一个变量,例如
1
2
3
4
5
6
7void main() {
eat("apple");
}
var eat = (str) {
print("eat $str");
};
输出:eat apple定义函数时,函数可以添加一组可选的位置参数(即该参数可有可无)
1. 将可选参数放在函数参数列表的最后位置
2. 在中括号[]添加一组参数
,例如
1 | void main() { |
- 定义函数时,可以指定命名参数
1. 将指定的命名参数放到函数参数列表的最后位置
2. 在大括号中指定一组命名参数
1 | void main() { |
注意: 指定命名参数和可选位置参数,不能同时使用
异步支持
Dart有非常多的返回Future或者Stream对象的函数,这些函数被称为异步函数。在Dart中async和await关键字支持了异步编程,因此可以写出和同步代码很像的异步代码。
Future
Future表示一个结果的最终完成,要么成功,要么失败,永远只返回一个结果。Future的调用结果还是一个Future对象,因此很方便进行链式调用。
在Future当中,常用的API有以下几种
Future.thenFuture执行异步任务后会在then中接收结果。then函数的定义如下:Future<R> then<R>(FutureOr<R> onValue(T value), {Function? onError});其实可以看到
then函数中定义了一个可选参数onError,源码中建议then函数中只使用onValue的回调,而错误应该使用catchError函数例如
1
2
3
4
5
6
7void main() {
Future.delayed(new Duration(seconds: 2), () {
return "Hello World";
}).then((value) => print("result : $value"));
}
输出
result : Hello WorldFuture.catchErrorFuture执行任务遇到错误时,则catchError会处理错误。catchError的
函数定义如下:Future<T> catchError(Function onError, {bool test(Object error)?});如果
then函数中已经添加了onError回调,则不再回调catchError函数。例如1
2
3
4
5
6
7
8
9void main() {
Future.delayed(new Duration(seconds: 2), () {
throw UnimplementedError("UnimplementedError");
}).then((value) => {print("result : $value")}, onError: (e) {
print("onError invoke");
}).catchError(() => print("catchError invoke"), );
}
输出:
onError invokeFuture.whenComplete有时候无论回调成功或者失败,都需要回调,就可以用whenComplete函数例如
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15void main() {
Future.delayed(new Duration(seconds: 2), () {
throw UnimplementedError("UnimplementedError");
})
.then((value) => {print("result : $value")}, onError: (e) {
print("onError invoke");
})
.catchError(
() => print("catchError invoke"),
)
.whenComplete(() => print("whenComplete invoke"));
}
输出
onError invoke
whenComplete invokeFuture.wait等待所有的异步函数执行完成后 在执行一些操作,可以使用wait函数。Future.wait接收一组Future数组参数,当所有的异步操作完成后,才执行then函数(这点其实类似于RxJava中zip操作符号)。当其中一个操作失败后,就会触发错误回调(onError函数或者catchError)。例如:
1
2
3
4
5
6
7
8
9
10
11
12void main() {
Future.wait([
Future.delayed(Duration(seconds: 3), () {
return "Hello";
}),
Future.delayed(Duration(seconds: 5), () {
return "World";
})
]).then((value) => print(value));
}
输出
[Hello, World]抛出错误例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14void main() {
Future.wait([
Future.delayed(Duration(seconds: 3), () {
return "Hello";
}),
Future.delayed(Duration(seconds: 5), () {
throw Exception("throw execption");
})
]).then((value) => print(value)).catchError((error) {
print(error);
});
}
输出:
Exception: throw execption
避免回调地狱问题(Future、async/await)
在Dart中可以有两种方式解决回调地狱问题,即Future对象和 async/await
利用Future API的特性Future执行完成后依然返回Future对象,所有很方便的进行链式调用1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27void main() {
getToken().then((token) {
return getUserInfo(token);
}).then((user) {
return saveUserInfo(user);
}).then((value) => print("result $value"));
}
Future getToken() {
return Future.delayed(Duration(seconds: 2), () {
return "token";
});
}
Future getUserInfo(String token) {
return Future.delayed(Duration(seconds: 2), () {
return UserInfo();
});
}
Future saveUserInfo(UserInfo info) {
return Future.delayed(Duration(seconds: 1), () {
return true;
});
}
输出
result trueasync/awaitasync和await是为了解决回调地狱问题,也就是让写异步代码就像写同步代码一样,逻辑看起来更清晰。注意:
-
async表示函数是异步的,返回的是一个Future对象。可以通过then函数获取结果回调
-await后面是一个Future函数,表示需要等待该函数执行完成后,才继续执行下一步
-await必须出现在async函数内部
例如:
1 | void main() { |
Stream
Stream也是用于接收异步事件数据,与Future不同的是,它可以接收多个异步事件操作结果。换句话说,就是可以同通过多次触发成功或者失败来传递数据结果和失败异常。常用于多次读取数据的异步场景,比如网路下载、文件读取等
例如:
1 | void main() { |