空检查不会在Dart中引起类型提升 [英] Null check doesn't cause type promotion in Dart

查看:53
本文介绍了空检查不会在Dart中引起类型提升的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在升级基于Flutter框架的个人软件包.我注意到这里在Flutter Text小部件源代码中,存在空检查:

I'm upgrading a personal package that is based on the Flutter framework. I noticed here in the Flutter Text widget source code that there is a null check:

if (textSpan != null) {
  properties.add(textSpan!.toDiagnosticsNode(name: 'textSpan', style: DiagnosticsTreeStyle.transition));
}

但是, textSpan!仍在使用运算符.是否不必须使用运算符将 textSpan 提升为不可为空的类型?但是,尝试删除该运算符会出现以下错误:

However, textSpan! is still using the ! operator. Shouldn't textSpan be promoted to a non-nullable type without having to use the ! operator? However, trying to remove the operator gives the following error:

An expression whose value can be 'null' must be null-checked before it can be dereferenced.
Try checking that the value isn't 'null' before dereferencing it.

这是一个独立的示例:

class MyClass {
  String? _myString;
  
  String get myString {
    if (_myString == null) {
      return '';
    }
    
    return _myString; //   <-- error here
  }
}

我收到一个编译时错误:

I get a compile-time error:

错误:类型为'String?'的值.无法从函数'myString'返回,因为它的返回类型为'String'.

Error: A value of type 'String?' can't be returned from function 'myString' because it has a return type of 'String'.

或者,如果我尝试获取 _mySting.length ,则会出现以下错误:

Or if I try to get _mySting.length I get the following error:

不能无条件地访问属性"length",因为接收者可以为"null".

The property 'length' can't be unconditionally accessed because the receiver can be 'null'.

我认为执行null检查将把 _myString 提升为不可为null的类型.为什么不呢?

I thought doing the null check would promote _myString to a non-nullable type. Why doesn't it?

我的问题已在GitHub上解决,因此我发布了答案在下面.

My question was solved on GitHub so I'm posting an answer below.

推荐答案

飞镖工程师Erik Ernst 在GitHub上的说法:

Dart engineer Erik Ernst says on GitHub:

类型提升仅适用于局部变量....实例变量的提升并不合理,因为它可能被运行计算的getter覆盖,并且每次调用它都会返回一个不同的对象.cf. dart-lang/language#1188 讨论与类型相似的机制促销,但基于动态检查,并带有相关讨论的链接.

Type promotion is only applicable to local variables. ... Promotion of an instance variable is not sound, because it could be overridden by a getter that runs a computation and returns a different object each time it is invoked. Cf. dart-lang/language#1188 for discussions about a mechanism which is similar to type promotion but based on dynamic checks, with some links to related discussions.

因此本地类型推广有效:

So local type promotion works:

  String myMethod(String? myString) {
    if (myString == null) {
      return '';
    }
    
    return myString;
  }

但是实例变量不提升.为此,您需要使用运算符手动告诉Dart您确保实例变量在这种情况下不为null:

But instance variables don't promote. For that you need to manually tell Dart that you are sure that the instance variable isn't null in this case by using the ! operator:

class MyClass {
  String? _myString;
  
  String myMethod() {
    if (_myString == null) {
      return '';
    }
    
    return _myString!;
  }
}

这篇关于空检查不会在Dart中引起类型提升的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆