Dart 为什么在检查可空性的if语句的范围内,可以将可空值视为可空值?
考虑这个演示:Dart 为什么在检查可空性的if语句的范围内,可以将可空值视为可空值?,dart,dart-null-safety,Dart,Dart Null Safety,考虑这个演示: void test(int? n) { if (n != null) { // let's make sure n is not null ++n; // ok; n is assumed to be non-null if (n < 0) { n = n.abs(); // ok; n is not null in inner scope } while (n != 0) { --n; // error: t
void test(int? n) {
if (n != null) { // let's make sure n is not null
++n; // ok; n is assumed to be non-null
if (n < 0) {
n = n.abs(); // ok; n is not null in inner scope
}
while (n != 0) {
--n; // error: the method '-' can't be unconditionally invoked because the receiver can be 'null'
}
}
}
无效测试(int?n){
如果(n!=null){//让我们确保n不是null
++n、 //确定;假定n为非null
if(n<0){
n=n.abs();//确定;n在内部作用域中不为null
}
而(n!=0){
--n、 //错误:无法无条件调用方法“-”,因为接收方可以为“null”
}
}
}
为什么
n
仍然被认为是int?
在而(…){…}
块中?我正在将VSCode与最新版本的Dart一起使用。与方法主体中前面的代码不同,while循环中的代码可以多次运行。您可以在循环的一次迭代中将null
分配给n
,因此可以对null
对象调用--
Dart的静态分析可以看出,对于非循环代码,n
将不会相对容易地为空,它只需遍历每一行,以查看是否存在可能的null
赋值。有了这个循环,Dart的分析就没那么聪明了。我猜这个检测无法完成,因为它需要实际运行循环的代码来确定n
是否会再次变为null
以下循环显示了一个示例,其中无法保证自动n
为null
,即使n
在--n
之前未指定为null
:
while(n!=0){
--n、 //错误:无法无条件调用方法“-”,因为接收方可以为“null”
如果(n==5){
n=零;
}
}
为了确定n
在--n
处是否可以null
,Dart的分析必须提前查看n
是否分配给null
在这种情况下,Dart的分析无法准确确定变量是否可以为
null
,这就是bang运算符存在的原因:
无效测试(int?n){
如果(n!=null){//让我们确保n不是null
++n、 //确定;假定n为非null
if(n<0){
n=n.abs();//确定;n在内部作用域中不为null
}
而(n!=0){
n=n!-1;
}
}
}
或者,您可以在特定示例中使用本地不可为空的变量:
无效测试(int?n){
如果(n!=null){//让我们确保n不是null
int nLocal=n;
++nLocal;//确定;n假定为非null
if(n<0){
nLocal=nLocal.abs();//确定;n在内部作用域中不为null
}
而(n!=0){
--非本地的;
}
}
}
与方法体前面的代码不同,while循环中的代码可以多次运行。您可以在循环的一次迭代中将null
分配给n
,因此可以对null
对象调用--
Dart的静态分析可以看出,对于非循环代码,n
将不会相对容易地为空,它只需遍历每一行,以查看是否存在可能的null
赋值。有了这个循环,Dart的分析就没那么聪明了。我猜这个检测无法完成,因为它需要实际运行循环的代码来确定n
是否会再次变为null
以下循环显示了一个示例,其中无法保证自动n
为null
,即使n
在--n
之前未指定为null
:
while(n!=0){
--n、 //错误:无法无条件调用方法“-”,因为接收方可以为“null”
如果(n==5){
n=零;
}
}
为了确定n
在--n
处是否可以null
,Dart的分析必须提前查看n
是否分配给null
在这种情况下,Dart的分析无法准确确定变量是否可以为
null
,这就是bang运算符存在的原因:
无效测试(int?n){
如果(n!=null){//让我们确保n不是null
++n、 //确定;假定n为非null
if(n<0){
n=n.abs();//确定;n在内部作用域中不为null
}
而(n!=0){
n=n!-1;
}
}
}
或者,您可以在特定示例中使用本地不可为空的变量:
无效测试(int?n){
如果(n!=null){//让我们确保n不是null
int nLocal=n;
++nLocal;//确定;n假定为非null
if(n<0){
nLocal=nLocal.abs();//确定;n在内部作用域中不为null
}
而(n!=0){
--非本地的;
}
}
}
请参见。请参见。bang运算符--!n代码>没有为我编译。错误:缺少选择器,例如“.identifier”或“[0]”。尝试添加选择器。
。但是,我可以做n=n!-1
。我遗漏了什么?@offworldwelcome当我写这个答案时,我以为我在dartpad中测试了这个语法,但你没有遗漏任何东西。这是无效的。但是,建议使用以下语法:。我将编辑我的答案以使其更准确。bang运算符--!n代码>没有为我编译。错误:缺少选择器,例如“.identifier”或“[0]”。尝试添加选择器。
。但是,我可以做n=n!-1
。我遗漏了什么?@offworldwelcome当我写这个答案时,我以为我在dartpad中测试了这个语法,但你没有遗漏任何东西。这是无效的。但是,建议使用以下语法:。我将编辑我的答案,使之更准确。