【问题标题】:why is it not possible to check a type as instance of `Null`为什么无法将类型检查为“Null”的实例
【发布时间】:2017-11-17 00:49:48
【问题描述】:

为什么我不能检查一个类型是否为Null

scala> val s:String = null
s: String = null

scala> s.isInstanceOf[Null]
<console>:13: error: type Null cannot be used in a type pattern or isInstanceOf test
       s.isInstanceOf[Null]

                 ^

【问题讨论】:

标签: scala


【解决方案1】:

x.isInstanceOf[C] 的一般约定是当且仅当xC 的一个实例时才返回true。作为任何事物的“实例”意味着x 不为空。

根据该规范,x.isInstanceOf[Null] 必须始终返回false,因为x 不会是Null实例,即使它恰好是null。编译器通过拒绝编译该测试来保护您免受这种混淆。

测试x 是否为null 的惯用方法是简单地使用

x == null

【讨论】:

    【解决方案2】:

    使用null 检查是否相等的更正确方法,因为您想明确查找引用相等。

    x eq null
    

    【讨论】:

    • == 是可交换的,因为 equals 必须是可交换的。因此,x == null 始终与null == x 相同,根据定义,x eq null 等价于。因此x == nullx eq null 一样正确。从我看到的 Scala 代码库来看,x == null 更符合习惯。
    • @sjrd 你是对的,但x eq null 更有效。引用 Scala 来源:表达式x == that 等价于if (x eq null) that eq null else x.equals(that)。所以x == null 变成if(x eq null) null eq null else ... 任何与null 的比较都是显式引用相等,而不是值相等,所以eq== 更有意义,恕我直言。
    • @sjrd 此外,如果您在 ScalaGitHub 存储库中搜索 " eq null"(带有双引号),您会看到很多与null 进行比较的示例与eq。所以我不确定你关于== 更惯用的说法是否有效。
    • @sjrd。顺便说一句,equals 显然 不可交换equals contract 规定 x.equals(null)false,但 null.equals(x)NPE
    • 啊,我应该更具体一点。事实上,equals 是不可交换的。我应该说的是equals 的规范要求x.equals(null)x ne null 时始终为false。这意味着当thatnull 时,x == null 的脱糖,正如你所说的if (x eq null) that eq null else x.equals(that) 导致if (x eq null) true else false。这显然等同于x eq null。所有 Scala 编译器都使用这种等式将x == null 优化为x eq null。这意味着它们同样正确和有效。
    猜你喜欢
    • 1970-01-01
    • 2019-10-13
    • 1970-01-01
    • 2015-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-09
    • 1970-01-01
    相关资源
    最近更新 更多