Dart--空安全、late、required、identical函数、常量构造函数

68 阅读3分钟

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
}