dart 最新语法之可空与非空类型 late关键字的作用

Dart 2.12 添加了late关键字,他有两个作用:

1)显式声明一个非空的变量,但不初始化

如下,_temperature如果不加late关键字,类实例化时此值是不确定的,无法通过静态检查,加上late关键字可以通过静态检查,但由此会带来运行时风险。

// Using null safety:
class Coffee {
  late String _temperature;
 
  void heat() { _temperature = 'hot'; }
  void chill() { _temperature = 'iced'; }
 
  String serve() => _temperature + ' coffee';
}
 
main() {
  var coffee = Coffee();
  coffee.heat();
  coffee.serve();
}

2)延迟初始化变量

这个作用看起来和第一点矛盾,实际上是同一个意思。看下面的例子,temperature变量看起来是在声明时就被初始化了,但因为late关键字的存在,如果temperature这个变量没有被使用的话,_readThermometer()这个函数不会被调用,temperature也就不会被初始化了。
 

late String temperature = _readThermometer(); // Lazily initialized.

未加入对 non-nullable 支持的 Dart 版本(目前稳定正式版本):

运行结果

1. 为什么需要加入 non-nullable 的支持?

加入 non-nullable 的支持,可以更加健全 Dart 的类型系统;从而使得类型系统更加安全,很大避免了类似 Java 中 NPE 问题,在 Dart 上则是对一个 Null 调用方法,会表现是 NoSuchMethodError 的异常。

2.1 当在声明定义变量时,一定要做初始化或者延迟初始化

解决方法:

声明时立即初始化

late 关键字实现延迟初始化

4.1 空类型声明符

//kotlin 声明可空类型
class Student {
    var name: String?//使用 ? 表示可空类型
    val age: Int
}
//dart 声明可空类型
class Student {
  String? name;//静态检查通过,使用 ? 表示可空类型,String? 则是可空类型 String
  int age; //静态检查错误
}

4.2 非空断言

有时候我们会遇到一个场景,就是经过判空处理,编译器无法智能分析出是否进行过非空判断,这时候它还是会提示你去进行判空处理,这时候就没必要去再判断一次,你可以使用非空断言,强行告诉编译器这是一个不为空的变量。

注意:使用非空断言的变量必须保证确实不为 null,否则会抛出异常。比如下面的例子,编译器是无法推断出已经做了非空判断的:

非空断言,来告诉编译器,在确定逻辑分支内,它是不可能为空的。

//dart 非空断言
void main() {
  String? name;
  if (isNotNull(name)) {//其实已经做了判空处理,运行实际上是 OK 的,
    // 但是编译器无法智能推断是否进行判空,所以还是提示报错
    print(name!.length);
  } else {
    print(0);
  }
}
 
bool isNotNull(String? param) {
  return param != null;
}

4.4 late final 用于 final 变量延迟初始化

late final 关键字主要用于常量延迟初始化,和 late 一样都是用于延迟初始化,但是 late final 只能被赋值一次。

late final int number;//声明顶层延迟初始化 final 变量
number = 100;//合法
number = 200;//非法

4.5 required 关键字

最开始 @required 是注解,现在它已经作为内置修饰符。主要用于允许根据需要标记任何命名参数(函数或类),使得它们不为空。因为可选参数中必须有个 required 参数或者该参数有个默认值。

void testFunc({required String param}) {//required 修饰符
    //do logic
}
//或者命名参数加默认值
void testFunc({String param = 'defalut value'}) {//默认值
 //do logic
}
//或者命名参数为可空类型
void testFunc({String? param}) {
 //do logic
}

4.6 ?[] 运算符

?[]主要为了给索引运算符 添加空判断的能力。

void main() {
    List<int>? numbers = [1, 2, 3];
    int? value = list?[0];  //value: 1
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值