我有一个问题,理解,并与生活,过度使用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中,编译器足够聪明,知道什么时候这些操作符是不必要的。我知道我可以从我试图访问的属性创建局部变量,但这同样是丑陋的;)
那么,为什么在这些情况下(以及许多其他情况下)需要!
和?
呢?对此我能做些什么呢?
2条答案
按热度按时间iyzzxitl1#
这就是可以为空的属性所发生的情况(因此你会得到这样的消息)。了解零安全:使用可空字段。
您应该可以通过将字段声明为
late
来解决此问题,如下所示这样就不需要在每次访问
position
时都加上一个bang。编译器会在适当的地方添加一个非空检查。当然,如果你在访问字段之前没有赋一个非空值,程序会失败。如果在晚期变量中解释
wz1wpwve2#
类的可空属性在两次访问之间仍然可以为空。
对于第一个示例,您可以提取变量,然后对其进行检查:
对于第二个示例,一种优雅的方法是..运算符:
如果希望GeoPosition不为空,则必须使其不可为空:
可以将位置字段
final
设置为不可变。使用
late
关键字时要小心,如果忘记初始化字段,就会出现类似!操作符的崩溃。