【问题标题】:An expression whose value can be 'null' must be null-checked before it can be dereferenced值可以为“空”的表达式必须先进行空检查,然后才能取消引用
【发布时间】:2021-01-29 12:19:35
【问题描述】:

我正在使用具有 null-safity 模式的 Dart。我在下一个代码中有问题。

List<JobModel> _jobList = [];
// ...
if(_jobList.isNotEmpty) { 
  for(var job in _jobList) {
     if(job.cmd_args != null) {
       numbersOfAlreadyActiveJobs.addAll(job.cmd_args.replaceAll('(', '').replaceAll(')','').split('=')[1].split(',').map(int.parse).toList());
     }  
  }

我 出现下一个错误:

但是为什么呢?我正在检查job.cmd_args != null

【问题讨论】:

  • job.cmd_args?.replaceAll
  • 或者,如果 cmd_args 不能为空,你可以使用 job.cmd_args!.replaceAll

标签: dart dart-null-safety


【解决方案1】:

Dart 只提升局部变量,这适用于类型和空值。

当您执行if (job.cmd_args != null) ... 时,它不允许编译器假定任何以后对job.cmd_args 的评估也将返回非空值。在不了解整个程序的情况下,它无法知道这一点(以确保没有任何东西实现JobModel,其中cmd_args 可能是在下一次调用时执行不同操作的getter)。即使它知道这一点,我们也不希望本地类型提升依赖于全局信息。这使得它太脆弱,你不能依赖它。有人在其他地方添加类可能会使您的代码不再升级,因此不再编译。

所以,你的测试还不够。

您可以做的是要么说“我知道我在做什么”,然后在 job.cmd_args!.replaceAll 中添加 !。这是对不可为空类型的运行时强制转换,如果在第二次读取时该值实际上最终为 null,它将抛出(它可能不会,但编译器对“可能”s 不满意)。

或者,您可以引入一个局部变量,可以将其提升为非空:

var args = job.cmd_args;
if (args != null) { 
  numberOfAlreadyActiveJobs.addAll(args.replaceAll(...));
}

这里引入一个新的本地变量args,然后检查那个是否是null。如果不是,那么您以后可以安全地将其用作非null,因为局部变量不会受到其他任何地方的代码的影响,因此编译器认为当您以后使用它时它确实具有相同的值。

【讨论】:

    猜你喜欢
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 2020-09-05
    • 1970-01-01
    • 2020-08-13
    • 2021-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多