1.Null Safety
空安全。
Null Safety可以帮助开发者避免一些日常开发中很难被发现的错误,并且额外的好处是可以改善性能。
Flutter2.2.0之后的版本都要求使用Null Safety。
(1)可空类型?
String? getData(url) {
if (url != null) {
return "this is server data";
} else {
return null;
}
}
void main() {
//Null Safety
//String? 就表示userName是一个可空类型
String? userName = 'Jack';
userName = null;
print('userName:$userName');
//int? 表示a是一个可空类型
int? a = 20;
a = null;
print('a:$a');
//调用返回值为可空类型的方法
print(getData(123));
print(getData(null));
}
2)类型断言!
void main() {
// !类型断言
String? str = 'this is Car';
//str = null;
//类型断言:如果str不为null,则打印出长度;如果为null,则抛出异常
print(str!.length);
// printlength(null);
printLengthSafety(null);
}
void printlength(String? str) {
print('Length:${str!.length}');
}
void printLengthSafety(String? str) {
try {
print('Length:${str!.length}');
} catch (e) {
print('str为空');
}
}
2.late关键字
(1)用于类里面的属性延迟初始化
class Person {
late String name;
late int age;
Person(this.name, this.age);
Person.xxx();
void setInfo(String name, int age) {
this.name = name;
this.age = age;
}
void printInfo() {
print('name:${this.name},age:${this.age}');
}
}
void main() {
Person p = new Person.xxx();
p.setInfo('Lisi', 30);
p.printInfo();
}
(2)可以用于抽象接口属性的延迟初始化
abstract class Inter {
late String name;
String? info;
}
3.required关键词
最开始@required是注解
现在它已经作为内置修饰符
主要用于允许根据需要标记任何命名参数(函数或类),使得它们不为空,因为可选参数中必须有个required
void printUserInfo(String userName, {int age = 10, String sex = '男'}) {
print('printUserInfo userName:$userName,age:$age,sex:$sex');
}
void printInfo(String userName, {required int age, required String sex}) {
print('printInfo userName:$userName,age:$age,sex:$sex');
}
class Person {
String name;
int age;
//表示name和age必须传入
Person({required this.name, required this.age});
void printInfo() {
print('name:${this.name},age:${this.age}');
}
}
class People {
String? name;
int age;
//表示name可以不传,age必须传入
People({this.name, required this.age});
void printInfo() {
print('name:${this.name},age:${this.age}');
}
}
void main() {
printUserInfo('AA');
printInfo('BBB', age: 30, sex: '女');
Person p = new Person(name: 'bob', age: 30);
p.printInfo();
People pp = new People(age: 30);
pp.printInfo();
}
4.identical函数
用法:bool identical(Object? a,Object? b)
检查两个引用是否指向同一个对象。
void main() {
// var o1 = new Object();
// var o2 = new Object();
// print(identical(o1, o2)); //false
// print(identical(o1, o1)); //true
//表示实例化常量构造函数
//o1和o2共享内存
// var o1 = const Object();
// var o2 = const Object();
// print(identical(o1, o2)); //true
// print(identical(o1, o1)); //true
//const关键词在多个地方创建相同的对象的时候,内存中只保存了一个对象
// print(identical([2], [2])); //false
// var a = [2];
// var b=[2];
// print(identical(a, b)); //false
// print(identical(const [2], const [2])); //true
// const a = [2];
// const b = [2];
// print(identical(a, b)); //true
}
5.常量构造函数
(1)常量构造函数需要以const关键字修饰
(2)const构造函数必须用于成员变量都是final的类
(3)如果实例化不加const修饰符,即使调用的是常量构造函数,实例化的对象也不是常量实例。
(4)实例化常量构造函数的时加上const修饰符,多个地方创建这个对象,如果传入的值相同,只会保留一个对象。
(5)Flutter中const修饰不仅仅是节省组件构建时的内存开销,Flutter在需要重新构建组件的时候不会去重构。
class Container {
final int width;
final int height;
const Container({required this.width, required this.height});
}
void main() {
// var c1 = Container(width: 100, height: 100);
// var c2 = Container(width: 100, height: 100);
// print(identical(c1, c2)); //false
// var c1 = const Container(width: 100, height: 100);
// var c2 = const Container(width: 100, height: 100);
// print(identical(c1, c2)); //true
var c1 = const Container(width: 100, height: 100);
var c2 = const Container(width: 150, height: 100);
print(identical(c1, c2)); //false
}