2

尽管没有明确说明Nothing 是所有类型的子类型,但这(除其他外)表明:

fun f(x:Float) { }
fun g(x:Char) { }

fun dead(q: Nothing) {
    f(q)
    g(q)
}

但是,这会因“未解决的引用”而失败:

fun dead(q: Nothing) {
    q.not()
}

这是错误还是功能?

笔记:

  1. 第一段代码编译(带有警告),第二段没有
  2. 可以使用Nothing类型化的接收器,例如调用toString()
  3. 这是合法的:{b:Boolean -> b.not()}(q)
  4. 也上调:(q as Boolean).not()
  5. Scala的等效问题
4

2 回答 2

4

NothingNothing有原因的。你不能在上面调用任何函数。此外not()仅适用于,Boolean因此它不存在于 上Nothing。实际上没有方法Nothing

/**
 * Nothing has no instances. You can use Nothing to represent "a value that never exists": for example,
 * if a function has the return type of Nothing, it means that it never returns (always throws an exception).
 */
public class Nothing private constructor()

该文档几乎解释了它的存在。

不过有一个漏洞。如果Nothing?从函数返回会发生什么?

fun dead(): Nothing? {
    return null
}

这是正确的。它只能返回null

@JvmStatic
fun main(args: Array<String>) {
    dead() // will be null
}

我不会说有一个有效的用例可以做到这一点,但这是可能的。

Nothing在树中表示虚无的示例:

sealed class Tree<out T>() {
    data class Node<out T>(val value: T,
                           val left: Tree<T> = None,
                           val right: Tree<T> = None): Tree<T>()
    object None: Tree<Nothing>()
}

这里Nothing表示没有子节点的叶节点。

于 2018-06-26T09:27:01.737 回答
3

前提本身没有意义。Nothing是一个无法实例化的类。你永远不会有一个包含Nothing实例的变量。

这意味着Nothing永远不能调用以参数为参数的函数,因为您无法获取Nothing要传递给它的实例。你在里面写的任何东西都是无关紧要的,像这样的函数一开始就存在。

Nothing被制作成所有类型的子类型,因此语言特性的某些用途与类型系统一样throw好用return。从本质上讲,编译器允许您Nothing在需要其他类型的地方传递 a,因为它知道您永远不会真正到达该代码(因为同样,您无法获得Nothing实例),所以什么都没有关系你进来了。

于 2018-06-26T09:43:49.320 回答