87

飞镖功能

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

void calculate({int factor}) {
  // ...
}

分析仪抱怨说:

参数 'factor' 的值不能为 'null',因为它的类型,并且没有提供非 null 默认值。

颤振小部件

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

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

  // ...
}

我收到以下错误:

参数 'key' 的值不能为 'null',因为它的类型,并且没有提供非 null 的默认值。


我该如何解决这个问题?

4

5 回答 5

154

为什么

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

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

解决方案

基本上有三种方法可以解决这个问题:

required

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

void calculate({required int factor}) {
  // ...
}

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

默认值

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

void calculate({int factor = 42}) {
  // ...
}

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

可空参数

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

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

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

  // ...
}

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

位置参数

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

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

void bar(int? param1) {} // bar(null) is valid.
于 2020-10-27T18:09:43.007 回答
12

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

MyPage({Key key = const Key("any_key")}) : super(key: key);

key像这样要求:

MyPage({required Key key}) : super(key: key);
于 2020-04-15T01:46:04.810 回答
8

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

  void calculate(int factor) {
     // ...
  }

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

calculate(12);

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

class Foo extends StatelessWidget {
  final String myVar;

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

  // ...
}

“可以跟随命名参数或可选位置参数(但不能同时跟随)”,请参见此处的文档:dart 参数

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

于 2020-12-21T21:15:51.797 回答
7

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

const ClassName({Key? key}) : super(key: key);

' ?' 表示可以nullable

于 2021-07-21T14:39:44.840 回答
6

为 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,
于 2021-06-27T08:19:40.577 回答