我无法理解Dart中的"Null"是什么

mez*_*oni 3 c# oop type-systems scala dart

我无法理解NullDart中的内容.

在C#语言中null是一个文字.这null是reference-type变量的默认值.

nullC#中没有类型.无法null通过点访问成员..

例:

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

在Dart中null有一种类型Null.但是NullDart中的bottom类型实例不是一种类型.

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

// How the `null` value with type of `Null`
// can be assigned to a `String` type?
String s = null;
Run Code Online (Sandbox Code Playgroud)

此代码在Dart编辑器中产生奇怪的警告.

"Tests for null should be done with '== null'".
print(s is NUll);
Run Code Online (Sandbox Code Playgroud)

但我不想要"测试null".我想测试一下Null.这不一样.

为什么Dart编辑器会出现这种奇怪的警告

我想测试如何工作Dart类型系统,但编辑给我这个消息.

我不明白,因为我无法理解同时的Null类型:

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

我欢迎开发人员的答案.

是否存在与面向对象编程(Dart语言规范中未记录)相关的任何魔法,关于如何将不兼容类型视为兼容类型?

PS

NullDart中的类型是完整的类,因此它是一个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";
}
Run Code Online (Sandbox Code Playgroud)

你可以看到这Null不是一种bottom类型.

在这里你可以看到它null不是一种bottom类型而是一种Null类型.

print(null.runtimeType == Null);
Run Code Online (Sandbox Code Playgroud)
true
Run Code Online (Sandbox Code Playgroud)

PS

我不明白为什么有些人不理解这些问题并导致矛盾的例子.

The static type of null is bottom.
Run Code Online (Sandbox Code Playgroud)

不对.类型nullNull类型,但不是bottom类型.

我已经证明了这一点

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

PS

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

或者可能是对手不是发展者?

或者Dart运行时可能不遵循语言规范而且反对者相信(或不知道?)这条规则不受尊重?

我认为null必须具有_Null未在源代码中声明的类型created internally in virtual machine.

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

谁对吗?我或你?

Pix*_*ant 6

规格

空值

保留字null表示空对象.

nullLiteral:null

;

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

null的静态类型是bottom.

使用bottom而不是Null的决定允许在任何地方分配null,而不受静态检查器的控制.

底部记录很少,我找不到太多的参考.但是,当规范讨论无效时,提到:

bottom是所有类型的子类型

所以,为了回答你的问题,看起来Null类型没有任何神奇之处,但是有一些神奇的文字正在进行中; 它有一种底部,这意味着它是所有类型的子类型.

由于null是唯一的例子Null,它是更正确的检查,如果事情== null不是is Null,我以为就是为什么你从编辑器警告.

  • 您将类与类混淆.`null`的类是`Null`,`null`的类型是`bottom`.类和类型是完全不同的东西,它们彼此无关.在OO中,类定义表示,类型定义行为. (3认同)

Gün*_*uer 3

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

检查s is Null结果,true但 Dart 风格指南似乎出于s == null我未知的原因强制要求(也许它更快)。

  • Dart 不是一种动态语言。Dart 是一种具有可选类型的语言。这与动态语言(例如 Ruby)不同。将 Null 实例分配给 String 类型或任何其他类型的变量在 Dart 中是无效的。因为Null不是String的子类型。这就是魔法。底部类型的值可以分配给任何类型。这是对的。但 Null 值不能分配给任何类型。魔法规则并不严肃。底部不是超类型而是子类型。也就是说,底部为 Null:true。空是底部:假。空是字符串:假。 (2认同)