在Dart中,我们通过构造函数简化了变量的初始化:
e.g。
class Foo
{
Bar _bar;
Foo(this._bar);
}
乍一看这看起来很方便。但根据我在95%的情况下的经验,你会期望发送到构造函数的内容应该是非null。
e.g。在C#中我会写:
public class Foo
{
private Bar bar;
public Foo(Bar bar)
{
if (bar == null)
throw new ArgumentNullException("bar");
this.bar = bar;
}
}
所以我的问题是Dart中针对空参数的最佳实践是什么?鉴于我们的语言功能基本上不鼓励它?
答案 0 :(得分:7)
在Dart的源代码中,他们抛出ArgumentError
大多数时候,他们不会检查null
,而是检查变量类型。
int codeUnitAt(int index) {
if (index is !int) throw new ArgumentError(index);
// ...
来源: dart/sdk/lib/_internal/lib/js_string.dart#L17
factory JSArray.fixed(int length) {
if ((length is !int) || (length < 0)) {
throw new ArgumentError("Length must be a non-negative integer: $length");
}
// ...
答案 1 :(得分:4)
这种初始化方法只会使您无需手动分配参数,检查和其他逻辑仍需要正文。我认为还是一个有用的功能。
class Foo {
var _bar;
Foo(this._bar) {
if(this._bar==null) throw new ArgumentError(_bar);
}
}
答案 2 :(得分:3)
这取决于你喜欢什么。
最常见的代码类似于您展示的C#:
if (bar == null) throw new ArgumentError("arg is null");
它提供了有用的错误消息,它可以防止以下代码执行错误操作(例如在null上随机格式化硬盘驱动器)。
我写道:
Foo(Bar bar) : _bar = bar {
if (bar == null) throw ArgumentError(...);
}
因为我发现它比其他选择更具可读性,但如果你愿意,你甚至可以写:
Foo(Bar bar) : this.bar = bar ?? throw ArgumentError(...);
使用assert(bar != null)
也可以。如果启用了断言,它只会捕获问题,但是如果只是为了保护自己(例如,在库中的内部类),那就足够了。对于面向公众的函数和类,我更喜欢if-throw。
答案 3 :(得分:0)
您可以使用assert进行检查
Chapter 2. A Tour of the Dart Language
assert(text != null);
断言语句仅在选中模式下有效。它们对生产模式没有影响。
因此断言便于开发,但不会影响生产中的性能。
如果您希望检查在生产中保留,您可以像在C#中那样进行
if (bar == null) {
throw new ArgumentError('Bar must not be null');
}
答案 4 :(得分:0)
您是否将“简化的初始化”称为“不鼓励进行空检查的语言功能” ...我可能误解了您的问题。
无论如何,这是我的处理方法:
class About {
final String title;
final String text;
const About({
customTitle,
customText,
}) :
title = customTitle ?? "",
text = customText ?? "";
}