我不明白Dart中的"Null"是什么



我不明白Dart中的Null是什么。

在C#语言中,null是一个文字。null是引用类型变量的默认值。

C#中的null没有类型。不可能通过点.来访问null的成员。

示例:

String s = null; // the default value of reference-type variable
null.GetType(); // Operator '.'  cannot be applied to operand of the type <null>

在Dart中,null的类型为Null。但Dart中Null类型的实例不是bottom类型。

根据类型继承,这在Dart中是如何工作的?

// How the `null` value with type of `Null`
// can be assigned to a `String` type?
String s = null;

这段代码在飞镖编辑器中产生了奇怪的警告。

"Tests for null should be done with '== null'".
print(s is NUll);

但我不想要"null测试"。我想要Null的测试。这不一样。

为什么在飞镖编辑器中出现这种奇怪的警告?

我想测试如何使用Dart类型的系统,但编辑器收到了这条消息。

我不明白,因为我不明白Null是如何同时键入的:

  1. 可以是所有类型的子类型
  2. 不能是所有类型的子类型

我欢迎开发人员的回答。

关于如何将不兼容的类型假定为兼容的类型,有没有与面向对象编程(Dart语言规范中没有记录)相反的魔力?

p.S.

Dart中的Null类型是完全类,因此它是regular type

我没有找到相反的官方文件(Null类型不是regular类型,而是bottom类型)。

这是我说话的证据。

class Null {
factory Null._uninstantiable() {
throw new UnsupportedError('class Null cannot be instantiated');
}
/** Returns the string `"null"`. */
String toString() => "null";
}

您可以看到Null不是bottom类型。

在这里,您可以看到null不是bottom类型,而是Null类型。

print(null.runtimeType == Null);
true

p.S.

我不明白为什么有些人不了解问题,并举出自相矛盾的例子。

The static type of null is bottom.

不对。null的类型是Null类型,而不是bottom类型。

我已经证明

  • null.runtimeType == Null但不是bottom类型
  • Null不是bottom类型(请参阅SDK中的源代码)

p.S.

为什么所有这些答案都与现实(运行时)的结论不一致?

或者可能是对手而不是开发者?

或者可能是Dart运行时没有遵循语言规范,而反对者相信(或者不知道?)这个规则没有得到遵守?

我认为null的类型必须是_Null,它不是在源代码中声明的,而是created internally in virtual machine

在这种情况下,我不能说_Null不是bottom类型,因为它隐藏在虚拟机中。

谁是对的?我还是你?

来自规范

保留字null表示null对象。

nullLiteral:空

null对象是内置类null的唯一实例。尝试实例化Null会导致运行时错误。这是一个试图扩展或实现Null的类的编译时错误。对null调用方法会产生NoSuchMethodError,除非该方法由类Null显式实现。

null的静态类型为底部。

使用bottom而不是Null的决定允许Null静态检查器在没有抱怨的情况下到处分配。

bottom的文档很差,我找不到太多参考资料。然而,当规范讨论void时,它提到:

bottom是所有类型的子类型

因此,为了回答您的问题,Null类型似乎没有什么神奇之处,但Null文本却有神奇之处;它有一个bottom类型,这意味着它是所有类型的子类型。

由于nullNull的唯一实例,因此检查某个== null是否比is Null更正确,我认为这就是编辑器发出警告的原因。

NullObject的一个子类型,由于Dart是一种动态语言,将null(Null的实例)分配给类型为String或任何其他类型的变量是有效的。静态类型检查必须有一个特殊规则,以便在将null分配给其他类型的变量时不会产生错误或警告。

检查s is Nulltrue的结果,但Dart风格指南似乎出于我不知道的原因(也许更快)而强制使用s == null

最新更新