首页 > 解决方案 > 什么时候没有合法的接收者?

问题描述

作为所有其他类型的子类型,可以将假设的Nothing类型化值传递给任何函数。但是,尽管这样的值可以用作接收器,toString()但它不能unary_!(除其他外)。

object Foo {
    def dead(q: Nothing): Unit = {
        println(q);
        q.toString();
        ((b: Boolean) => !b)(q);
        !q; // value unary_! is not a member of Nothing
    }
}

这是错误还是功能?

笔记:

  1. 这是我在 Kotlin 上提出的等效问题的 Scala 版本。
  2. 上调作品:!(q.asInstanceOf[Boolean])

标签: scalainheritancetypessubtypingbottom-type

解决方案


你不需要向上转型。您只需要指定一些具有方法的类型unary_!

def dead(q: Nothing): Unit = {
  !(q: Boolean)
}

如果没有明确的类型归属,该方法unary_!根本无法解析,因为即使Nothing是 的子类型Boolean它也不是 的子类Boolean因此编译器无法unary_!在 的继承层次结构中找到方法Nothing

您可以定义此类方法和函数的事实也不是错误。以下是一个完全有效的程序,它使用具有输入类型的函数Nothing来产生完全有意义的结果0,而不会抛出任何错误或类似的东西:

def foo[X](xs: List[X], f: (Int, X) => Int) = {
  xs.foldLeft(0)(f)
}

foo(Nil, (i: Int, n: Nothing) => 42)

类型系统中的存在Nothing是一个非常好的主意,因为它是一个初始对象(对于其他类型A,只有一个函数Nothing => A),并且它简化了很多事情,因为它不会强迫你处理所有类型的奇怪的角落案例。


推荐阅读