dart bang算子的不必要使用

iyfjxgzm  于 2022-12-16  发布在  其他
关注(0)|答案(2)|浏览(130)

我有一个问题,理解,并与生活,过度使用bang运算符在 dart /Flutter。
请看这个例子:

if(model != null && model!.someValue != null) {
    print(model!.someValue!);
}

第一个条件检查是验证模型是否不为空。在第二个条件中,我必须在模型后面放入一个bang操作符,否则编译器会给我一个The property 'someValue' can't be unconditionally accessed because the receiver can be 'null'错误。但是为什么有必要这样做呢?我刚刚检查了变量!print(model!.someValue!);行也是如此。
另一个例子,我有这些类:

class GeoPosition {
  double lat = 0;
}
      
class Wrapper {
    GeoPosition? position;
}
 
...
      
Wrapper wrapper = Wrapper();
wrapper.position = GeoPosition();     
wrapper.position!.lat = 1;

现在为什么我需要把这个bang操作符(或?操作符)放在position之后呢?我刚刚在Wrapper示例中创建了一个新的GeoPosition示例-- position不能为空。
我最好的猜测是编译器不能看到或理解类的当前上下文。但是在Typescript中,编译器足够聪明,知道什么时候这些操作符是不必要的。我知道我可以从我试图访问的属性创建局部变量,但这同样是丑陋的;)
那么,为什么在这些情况下(以及许多其他情况下)需要!?呢?对此我能做些什么呢?

iyzzxitl

iyzzxitl1#

这就是可以为空的属性所发生的情况(因此你会得到这样的消息)。了解零安全:使用可空字段。
您应该可以通过将字段声明为late来解决此问题,如下所示

class Wrapper {
  late GeoPosition position;
}

Wrapper wrapper = Wrapper();
wrapper.position = GeoPosition();     
wrapper.position.lat = 1;

这样就不需要在每次访问position时都加上一个bang。编译器会在适当的地方添加一个非空检查。当然,如果你在访问字段之前没有赋一个非空值,程序会失败。
如果在晚期变量中解释

wz1wpwve

wz1wpwve2#

类的可空属性在两次访问之间仍然可以为空。

对于第一个示例,您可以提取变量,然后对其进行检查:

var someValue = model?.someValue;
    if(someValue != null) {
       print(someValue); // not null
    }

对于第二个示例,一种优雅的方法是..运算符:

Wrapper wrapper = Wrapper();
    wrapper. Position = GeoPosition()..lat = 1;

如果希望GeoPosition不为空,则必须使其不可为空:

class Wrapper {
      GeoPosition position;
    
      Wrapper(this.position);
    }

可以将位置字段final设置为不可变。
使用late关键字时要小心,如果忘记初始化字段,就会出现类似!操作符的崩溃。

相关问题