由于它在 Dart 中的类型,该参数的值不能为 'null'

cre*_*not 52 dart flutter dart-null-safety

飞镖功能

我有以下 Dart 函数,我现在使用空安全:

void calculate({int factor}) {
  // ...
}
Run Code Online (Sandbox Code Playgroud)

分析器抱怨说:

参数“factor”因其类型而不能具有“null”值,并且未提供非空默认值。

颤振小部件

这也是我StatelessWidget在 Flutter 中的情况:

class Foo extends StatelessWidget {
  const Foo({Key key}): super(key: key);

  // ...
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

参数 'key' 因其类型而不能具有 'null' 值,并且未提供非空默认值。


我该如何解决这个问题?

cre*_*not 101

为什么

发生这种情况的原因是因为启用空安全,您的不可空参数factorkey 不能null.

在函数和构造函数中,这些值可能null在没有命名参数的情况下调用函数时:calculate()Foo()。然而,因为类型 ( intand Key) 是不可为空的,所以这是无效的代码 - 它们永远不能为空。

解决方案

解决这个问题的方法主要有以下三种:

required

这可能是这个问题最常见的解决方案,它表明必须设置一个变量。这意味着如果我们有(注意required关键字):

void calculate({required int factor}) {
  // ...
}
Run Code Online (Sandbox Code Playgroud)

我们指出factor必须始终指定参数,这解决了问题,因为只有calculate(factor: 42)等人。将是该函数的有效调用。

默认值

另一种解决方案是提供默认值。如果我们的参数有默认值,我们可以安全地在调用函数时不指定参数,因为将使用默认值:

void calculate({int factor = 42}) {
  // ...
}
Run Code Online (Sandbox Code Playgroud)

现在,calculate()调用将42用作factor,这显然是非空的。

可空参数

第三种解决方案是您真正想要考虑的问题,即您是否想要一个可为空的参数?如果是这样,则在您的函数中使用该参数时,您必须对其进行空检查。

但是,这是您最常希望解决Key key问题的方式,因为您并不总是想为 Flutter 中的小部件提供键(请注意可空Key?类型):

class Foo extends StatelessWidget {
  const Foo({Key? key}): super(key: key);

  // ...
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以在Foo()不提供密钥的情况下安全地构建。

位置参数

请注意,这同样适用于位置参数,即它们可以为可空或不可为空,但是,它们不能被注释required并且不能具有默认值,因为它们总是需要传递。

void foo(int param1) {} // bar(null) is invalid.

void bar(int? param1) {} // bar(null) is valid.
Run Code Online (Sandbox Code Playgroud)


Ben*_*sal 16

constructor 如果我从类指向中收到此错误key,我会?在前面添加一个“ ”标记,Key如下所示:

const ClassName({Key? key}) : super(key: key);
Run Code Online (Sandbox Code Playgroud)

' ?' 表示可以nullable


小智 13

为 Eg 添加所需的功能

required Key key,
    required this.id,
    required this.name,  
    required this.code,  
    required this.img,  
    required this.price,
    required this.promotionPrice,
    required this.size,
    required this.color,
Run Code Online (Sandbox Code Playgroud)

  • 但如果我不想需要一个变量怎么办 (2认同)

iDe*_*ode 8

这是 Dart 添加不可为空特性的主要原因。因为,您要传递Key给超类,这可能是null,所以您要确保它不为空。您可以做的是要么根本不使用key,要么为其提供默认值或使其成为required。喜欢:

MyPage({Key key = const Key("any_key")}) : super(key: key);
Run Code Online (Sandbox Code Playgroud)

或者key像这样要求:

MyPage({required Key key}) : super(key: key);
Run Code Online (Sandbox Code Playgroud)

  • 新的不可为空关键字将是“required”而不是“@required” (2认同)

oli*_*iaz 7

作为先前@creativecreatorormaybenot答案的附加信息,您还可以使用默认情况下强制性的位置参数(无大括号),因此不可为空。

  void calculate(int factor) {
     // ...
  }
Run Code Online (Sandbox Code Playgroud)

并在不命名参数的情况下调用:

calculate(12);
Run Code Online (Sandbox Code Playgroud)

这些类型的参数可以通过这种方式在构造函数上使用:

class Foo extends StatelessWidget {
  final String myVar;

  const Foo(this.myVar, {Key? key}): super(key: key);

  // ...
}
Run Code Online (Sandbox Code Playgroud)

“可以跟随命名参数或可选位置参数(但不是两者)”,请参阅此处的文档:dart parameters

关于命名参数和位置参数之间差异的有趣答案:Dart 中命名参数和位置参数之间的区别是什么?


小智 6

在构造函数中的变量前添加必需的关键字,并添加“?” 钥匙旁边。

  MyHomePage({Key? key, required this.title}) : super(key: key);
Run Code Online (Sandbox Code Playgroud)