Вызов любого метода на Nothing - PullRequest
0 голосов
/ 26 июня 2018

Хотя явно не указано , что Ничто не является подтипом всех типов, это (среди прочего) предполагает это:

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. Upcast тоже: (q as Boolean).not()
  5. Эквивалентный вопрос для Scala

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Само помещение не имеет смысла. Nothing - это класс, который не может быть создан. У вас никогда не будет переменной, содержащей экземпляр Nothing.

Это означает, что функция, которая принимает Nothing в качестве параметра, никогда не может быть вызвана, потому что вы не можете получить экземпляр Nothing для передачи ему. Все, что вы пишете внутри, не имеет значения, так как такая функция существует в первую очередь.

Nothing действует как подтип для всех типов, так что определенные варианты использования языковых функций, таких как throw и return, прекрасно работают с системой типов. По сути, компилятор позволяет передавать Nothing в местах, где требуется какой-то другой тип, потому что он знает, что вы никогда не достигнете этого кода (потому что, опять же, вы не можете получить экземпляр Nothing), поэтому не имеет значения, что вы передаете.

0 голосов
/ 26 июня 2018

Nothing - это Nothing по причине. Вы не можете вызывать какие-либо функции на нем. Кроме того, 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 обозначает листовой узел без дочерних элементов.

...