新特性
Null safety
空安全 - 帮助开发者避免一些日常开发中很难发现的错误,并且额外的好处是可以改善性能。
1
2
3
4
| // 非空类型
int a = 123;
// 报错 - A value of type 'Null' can't be assigned to a variable of type 'int'.
a = null;
|
1
2
3
4
| // String? 表示 a 是一个可空类型
String? a = 'hello';
a = null;
print(a); // null
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| // 可空数值
int? a = 123;
// 可空字符串
String a = 'hello';
// 可空的List
List<String>? list = ['11', '22', '33'];
// 返回值可空的方法
String? getData(String value) {
if (value) {
return value;
}
return null;
}
|
类型断言
1
2
3
4
| String? str = 'hello';
str = null;
// 报错 - The property 'length' can't be unconditionally accessed because the receiver can be 'null'.
print(str.length);
|
1
2
3
4
| String? str = 'hello';
str = null;
// 类型断言:如果str 不等于空就会打印出长度,如果等于空会抛出异常 - Null check operator used on a null value
print(str!.length);
|
1
2
3
4
5
6
7
| void printLenght(String? str) {
try{
print(str!.lenght);
}catch(err) {
print('str is null');
}
}
|
late 关键字
主要用于延迟初始化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| class Person {
String name; // 报错 - Non-nullable instance field 'name' must be initialized
int age;
void setInfo(String name, int age) {
this.name = name;
this.age = age;
}
String getInfo() {
return '${this.name},${this.age}';
}
}
void main() {
Person p = new Person();
}
|
解决:late
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| class Person {
late String name; // 报错 - Non-nullable instance field 'name' must be initialized
late int age;
void setInfo(String name, int age) {
this.name = name;
this.age = age;
}
String getInfo() {
return '${this.name},${this.age}';
}
}
void main() {
Person p = new Person();
}
|
required关键字
内置修饰符 - 主要用于允许根据需要标记任何命名参数(函数或类),使得他们不为空,因为可选参数中必须有个 require
1
2
3
4
5
6
7
8
| // 当没有指定默认值的时候 - The parameter 'age' can't have a value of 'null' because of its type, but the implicit default value is 'null'
String getUserInfo(String name, {int age, String sex}) {
return '${name},${age},${sex}';
}
void main() {
print(getUserInfo('张三', age: 20, sex: '男'));
}
|
改为:
1
2
3
4
5
6
7
| String getUserInfo(String name, {required int age, required String sex}) {
return '${name},${age},${sex}';
}
void main() {
print(getUserInfo('张三', age: 20, sex: '男')); // 张三,20,男
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| // 必须传入的命名参数
class Person {
String name;
int age;
// 表示name age 必须传入
Person({required this.name, required this.age});
String getInfo() {
return '${this.name},${this.age}';
}
}
void main() {
Person p = new Person(name: '张三', age: 20);
print(p.getInfo()); // 张三,20
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| // 表示 age 可选传入
class Person {
String name;
int? age;
Person({required this.name, this.age});
String getInfo() {
return '${this.name},${this.age}';
}
}
void main() {
Person p = new Person(name: '张三');
print(p.getInfo()); // 张三,null
}
|