该参数的值不能为“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 参数 factor
或 key
不能 是 @ 987654323@.
在函数和构造函数中,当函数在没有命名参数的情况下调用时,这些值可能为null
:calculate()
或Foo()
。但是,由于类型(int
和 Key
)是不可为空的,这是无效代码 - 它们决不能为空。
解决方案
基本上有三种方法可以解决这个问题:
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 param
或int? 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 中的类型的主要内容,如果未能解决你的问题,请参考以下文章