最初为空的不可空容器或最初可为空且为空的容器哪个更好?
What's better, an initially empty non-nullable or an initially nullable and null container?
假设您正在管理建筑物内居民拥有的自行车的序列号列表,并objective提前计划建造额外的安全自行车存放处。
有些人当然没有自行车。
在 Dart > 2.12 中(null safety)你可以
使用不可为 null 的 List<String>
并将其初始化为空列表
class Resident {
String name;
List<String> bicycles = [];
}
或者您可以使用可为 null 的 List<String>
并使用 null
作为标志来表示某人没有自行车。
class Resident {
String name;
List<String>? bicycles;
}
这两种设计当然都是可行的,但在未来是否会发现一个明显优于另一个——例如,更符合新 Dart 的习惯?换句话说,最初为空的不可空容器或最初可为空且为空的容器哪个更好?
即使我计算所需的位数,也不是很清楚。在第一种情况下会浪费存储空间来构建一个空列表,但在第二种情况下也会浪费存储空间——尽管它是未知的,并且可能依赖于实现——数量。
如果您想表示拥有 none 某物,则优先使用具有空状态的不可空容器类型而不是可空类型。
- 对于可为 null 的容器,您可能需要处理容器为空的情况,现在您必须做额外的工作来检查所有地方的
null
。
同时,处理空容器通常不需要任何额外工作。对比:
// Nullable case.
final bicycles = resident.bicycles;
if (bicycles != null) {
for (var bicycle in bicycles) {
doSomething(bicycle);
}
}
和
/// Non-nullable case.
for (var bicycle in resident.bicycles) {
doSomething(bicycle);
}
- 您可以尝试在容器变空时重置对
null
的引用,这样就没有两种情况需要处理,但如上所述,空情况通常是免费的,所以'做更多的工作通常是没有收获的。此外,重置引用可能需要 很多 的额外工作:
var list = [1, 2, 3];
mutateList(list);
if (list.isEmpty) {
list = null;
}
如果 mutateList
可以从 list
中删除元素,那么 每个 调用者都需要做额外的工作来将空的 List
替换为 null
.
- 即使您不关心用
null
替换空容器,在转换到非空容器时您仍然会有不同的行为。考虑:
var sam = Resident();
var samsBicycles = sam.bicycles;
sam.addBicycle();
您希望 samsBicycles
是什么?如果 Resident.bicycles
最初是 null
,那么 samsBicycles
将保持 null
并且不再引用与 sam.bicycles
. 相同的对象
假设您正在管理建筑物内居民拥有的自行车的序列号列表,并objective提前计划建造额外的安全自行车存放处。
有些人当然没有自行车。
在 Dart > 2.12 中(null safety)你可以
使用不可为 null 的 List<String>
并将其初始化为空列表
class Resident {
String name;
List<String> bicycles = [];
}
或者您可以使用可为 null 的 List<String>
并使用 null
作为标志来表示某人没有自行车。
class Resident {
String name;
List<String>? bicycles;
}
这两种设计当然都是可行的,但在未来是否会发现一个明显优于另一个——例如,更符合新 Dart 的习惯?换句话说,最初为空的不可空容器或最初可为空且为空的容器哪个更好?
即使我计算所需的位数,也不是很清楚。在第一种情况下会浪费存储空间来构建一个空列表,但在第二种情况下也会浪费存储空间——尽管它是未知的,并且可能依赖于实现——数量。
如果您想表示拥有 none 某物,则优先使用具有空状态的不可空容器类型而不是可空类型。
- 对于可为 null 的容器,您可能需要处理容器为空的情况,现在您必须做额外的工作来检查所有地方的
null
。 同时,处理空容器通常不需要任何额外工作。对比:
和// Nullable case. final bicycles = resident.bicycles; if (bicycles != null) { for (var bicycle in bicycles) { doSomething(bicycle); } }
/// Non-nullable case. for (var bicycle in resident.bicycles) { doSomething(bicycle); }
- 您可以尝试在容器变空时重置对
null
的引用,这样就没有两种情况需要处理,但如上所述,空情况通常是免费的,所以'做更多的工作通常是没有收获的。此外,重置引用可能需要 很多 的额外工作:
如果var list = [1, 2, 3]; mutateList(list); if (list.isEmpty) { list = null; }
mutateList
可以从list
中删除元素,那么 每个 调用者都需要做额外的工作来将空的List
替换为null
. - 即使您不关心用
null
替换空容器,在转换到非空容器时您仍然会有不同的行为。考虑:
您希望var sam = Resident(); var samsBicycles = sam.bicycles; sam.addBicycle();
samsBicycles
是什么?如果Resident.bicycles
最初是null
,那么samsBicycles
将保持null
并且不再引用与sam.bicycles
. 相同的对象