问题描述
Dart函数
我具有以下Dart函数,现在正在使用null安全性:
void calculate({int factor}) {
// ...
}
分析仪抱怨:
参数“ factor”由于其类型而不能具有“ null”值,并且未提供非null的默认值。
Flutter小部件
在Flutter中,我的StatelessWidget
也是如此:
class Foo extends StatelessWidget {
const Foo({Key key}): super(key: key);
// ...
}
我收到以下错误:
由于类型,参数'key'的值不能为'null',并且不提供非null的默认值。
如何解决此问题?
解决方法
为什么
发生这种情况的原因是,由于启用了 null安全性,您的 non-nullable 参数factor
或key
不能是null
。
在函数和构造函数中,当在没有命名参数null
或calculate()
的情况下调用函数时,这些值可能为Foo()
。但是,由于类型(int
和Key
是不可空的,因此这是无效的代码-它们不得为空。
解决方案
基本上有三种解决方法:
required
这可能是解决此问题的最常见方法,它表明必须设置变量 。这意味着如果有(请注意required
关键字):
void calculate({required int factor}) {
// ...
}
我们指出必须始终指定factor
参数,这解决了这个问题,因为只有calculate(factor: 42)
等。将是该函数的有效调用。
默认值
另一种解决方案是提供默认值。如果我们的参数具有默认值,则在调用函数时我们无法安全地指定参数,因为将使用默认值:
void calculate({int factor = 42}) {
// ...
}
现在,calculate()
调用将使用42
作为factor
,这显然不是null。
可空参数
第三个解决方案是您真正要考虑的东西,即是否要具有可为空的参数?如果是这样,则在函数中使用该参数时,必须将其作空检查。
但是,这是您最常见的解决Key key
问题的方法,因为您并不总是希望在Flutter中为小部件提供密钥(请注意可为空的Key?
类型):
class Foo extends StatelessWidget {
const Foo({Key? key}): super(key: key);
// ...
}
现在,您可以安全地构造Foo()
,而无需提供密钥。
作为上一个@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?
,如果我从指向 constructor
的类的 key
中得到这个错误,我会添加一个“?
”标记像这样在Key
面前:
const ClassName({Key? key}) : super(key: key);
'?
' 表示可以nullable
为 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,