该参数的值不能为“null”,因为它在 Dart 中的类型

Posted

技术标签:

【中文标题】该参数的值不能为“null”,因为它在 Dart 中的类型【英文标题】:The parameter can't have a value of 'null' because of its type in Dart 【发布时间】:2021-02-10 02:05:59 【问题描述】:

飞镖功能

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

void calculate(int factor) 
  // ...

分析器抱怨:

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

颤振小部件

我在 Flutter 中的 StatelessWidget 也是这样:

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

  // ...

我收到以下错误:

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


我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

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

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

或者像这样要求key

MyPage(required Key key) : super(key: key);

【讨论】:

新的不可为空的关键字将是 required 而不是 @required ? 嗨@iDecode :) 我将奖励你,因为your question 现已合并。我不确定哪种赏金合适 - 我希望这对你有用。 @creativecreatorormaybenot 谢谢,但我期待一个更大的,因为你已经获得了 (32 + 61) x 10 = 930 次。我不会对答案说太多,但可以肯定的是这个问题。反正我也不叫你提,全看你自己了。 @iDecode 我明白了;)我没有那样想。我的问题是回头看,质量通常不能证明赏金是合理的,所以我犹豫是否夸大其词。我会看看是否有可能创造另一个赏金,但我不确定。该系统非常严格。 @creativecreatorormaybenot 别担心,你是个好人。你应得的。虽然您可以再次创建新的赏金(下次不能少于 300),但请不要。我对你没有任何遗憾:)【参考方案2】:

为什么

发生这种情况的原因是因为启用了 null 安全,您的 non-nullable 参数 factorkey 不能 是 @ 987654323@.

在函数和构造函数中,当函数在没有命名参数的情况下调用时,这些值可能nullcalculate()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.

【讨论】:

类 SectionListTileWidget 扩展 StatefulWidget final BuildContext tileContext; final IconData tileLeadingIcon;最终颜色 tileLeadingIconColor;最终字符串 tileTitle;最终功能 tileOnTapAction; SectionListTileWidget(需要this.tileContext,需要this.tileLeadingIcon,需要this.tileLeadingIconColor,需要this.tileTitle,需要this.tileOnTapAction); @override _SectionListTileWidgetState createState() => _SectionListTileWidgetState(); 我怎样才能使“tileLeadingIconColor”可以为空,这样如果我没有 tileLeadingIconColor (null),那么我可以使用 Colors.green,否则想要使用用户传递的 tileLeadingIconColor。请建议我该怎么做。非常感谢。 我同意你的看法,这是可选的选择:使用required int paramint? param【参考方案3】:

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

  void calculate(int factor) 
     // ...
  

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

calculate(12);

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

class Foo extends StatelessWidget 
  final String myVar;

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

  // ...

“可以跟在命名参数之后,也可以跟在可选的位置参数之后(但不能同时跟在两者后面)”,请参阅此处的文档:dart parameters

关于命名参数和位置参数之间差异的有趣答案:What is the difference between named and positional parameters in Dart?

【讨论】:

【参考方案4】:

为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,

【讨论】:

【参考方案5】:

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

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

'?'表示可以是nullable

【讨论】:

以上是关于该参数的值不能为“null”,因为它在 Dart 中的类型的主要内容,如果未能解决你的问题,请参考以下文章

【求助】关于JQuery获取不到值,请求参数为Null

Dart 语法糖?. 和??

python none和null的区别

值不能为 null 或空. 参数名: value

Dart 语法零散知识

Dart 语法零散知识