非空实例字段必须被初始化

70
class Foo {
  int count; // Error
  void bar() => count = 0;
}

为什么我在bar方法中已经初始化了,但还是看到一个错误?如果count被标记为final,我可以理解这个错误。

5个回答

149

(在 Dart 2.12 之前,你的代码是没问题的,没有空值安全)

有了空值安全,Dart 不知道你是否真的给 count 赋了一个值。Dart 在两个阶段初始化对象,并且在构造函数体执行时,Dart 期望所有成员变量已经被初始化。因为你的成员变量是非空的,并且还没有被初始化为非空值,所以会出现错误。

1. 在声明时:

int count = 0;

2. 在初始化形式参数中:

Foo(this.count);

3. 在初始化列表中:

Foo() : count = 0;

4. 使用late关键字

这意味着您承诺在任何尝试使用它们之前,变量将被初始化。

class Foo {
  late int count; // No error
  void bar() => count = 0;
}

5. 将变量设为可空:

class Foo {
  int? count; // No error
  void bar() => count = 0;
}

然而,这将要求所有访问在使用成员之前明确检查它们是否为null。


另请参阅:在Dart中立即或在构造函数中分配变量?


9
使用late关键字在变量首次读取时初始化变量,而不是在创建变量时进行初始化。
class Questionz {
    late String questionText;
    late bool questionAnswer;

    Questionz({required String t, required bool a}) {
        questionText = t;
        questionAnswer = a;
    }
}

0
使用"?"修饰符使字段可为空,允许其未初始化。这种方法通常是首选!请参考以下代码片段作为示例。
String? myField;

-2
在我的情况下,我发现将问号和感叹号赋给变量是有帮助的:
 double? _bmi; // adding ? to the double 

  String calculateBMI(){

    _bmi=weight/pow(height/100, 2);
     return  _bmi!.toStringAsFixed(1);// adding ! to the private variable


}

 String getResult(){
    if(_bmi!>=25){ //adding ! to the private variable
     return 'Overweight';
     } else if (_bmi!>=18.5)
   {
      return 'normal';
    }else{return 'underweight';}

1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

-3

如果您正在使用pubspec.yaml:

environment: sdk: ">=2.12.0 <3.0.0"

请更改为:environment: sdk: ">=2.7.0 <3.0.0"

2.12.0 空安全特性已开启,而 2.7.0 空安全特性已关闭

提示:不要复制粘贴,手动更改

有关更多信息,请参见https://dart.dev/null-safety

对于空安全,请在变量后面加上 ?,例如 var a?,并在使用变量时在变量后面加上 !,例如:if(a!){}


3
所以,你基本上是告诉我选择退出空安全?抱歉,这不是我要找的东西! - iDecode
你来决定吧兄弟...我不想在项目中使用空安全,但是却得到了相同的错误。 - Milind Gour
在编程中,为了避免出现空指针异常,可以在变量后面加上 ? ,例如:var a?。另外,在使用变量时,可以在变量后面加上 ! 来表示这个变量不为空,例如:if(a!)。 - Milind Gour
2
首先,你能在没有空值安全的情况下停留多久?其次,我已经在我的答案中提供了那个解决方案。 - iDecode
我的错误是由于在异步函数中使用await和then,我从另一个类中获取了一个返回future的值,所以错误是因为无法返回带有?的变量,这是由于await和then的原因。 - Milind Gour
4
这个回答被标记为“不是答案”,但它确实是一个答案。它是一个有不良副作用的答案,因此它被点踩了,这也是对于没有用处的答案应该采取的正确行动。提供真诚努力回答问题的答案不应该被删除(除非当然它们只是一个链接)。 - Jeremy Caney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接