Эта статья была размещена Prefert вScalaCoolБлог команды.
мы вПогружение в Kotlin (2): дизайн структуры типа KotlinСистема типов Kotlin была кратко представлена в .
Упоминается в статье:Any
Типы в Котлиневсе ненулевые типы(бывший:String
, Int
) корневого типа.
Когда нам нужно взаимодействовать с Java, Kotlin использует параметры метода Java и возвращаемые типы, используемые вObject
введите какAny
(точнее как "тип платформы"). При использовании в функциях KotlinAny
, он скомпилирован в байт-код JavaObject
.
Что такое тип платформы?
Типы платформы — это, по сути, типы, для которых в Kotlin нет информации о допустимости значений NULL — все ссылочные типы Java ведут себя как типы платформы в Kotlin. При работе со значением типа платформы в Kotlin его можно рассматривать либо как тип, допускающий значение NULL, либо как ненулевой тип.
Введение типов платформ — это компромисс дизайна, когда Kotlin совместим с Java. Только представьте, если бы все значения из Java обрабатывались как ненулевые, было бы проще писать опасный код. И наоборот, если значения Java принудительно обнуляются, это приведет к большому количеству ошибок.
null
Осмотр. Всестороннее рассмотрение, тип платформы является компромиссным дизайном.
В Яве,Object
Типы находятся на верхнем уровне своей системы типов. Если Kotlin на 100 % совместим с Java, можем ли мы сказать, что Any также является типом верхнего уровня среди всех типов в Kotlin? В предыдущей статье меня эта проблема тоже беспокоила, а официал внятного заявления не сделал. Но что мы можем заметить, так это то, что в Kotlin была введена концепция «обнуляемых типов», которая, вероятно, повлияет на иерархию системы.
Прежде чем приступить к изучению корневых типов, давайте проясним два понятия: наследование (Inheriting
) и подтип (Subtyping
).
Разница между наследованием и подтипом
Это, казалось бы, легкий, но не такой уж простой вопрос: что же такое подтипирование (Subtyping
)? мы былиПодтипы и классы типов (1)В этом блоге обсуждается этот вопрос. Если у вас есть только опыт разработки на языке программирования Java, легко впасть в заблуждение — отношение наследования определяет отношение типа родитель-потомок. Потому что в Java классы и типы в большинстве случаев «эквивалентны» (до дженериков Java).
На самом деле «наследование» и «подтипирование» — это два совершенно разных понятия.
-
подтипЯдром является отношение замещения типа (мы также можем назвать его полиморфизмом подтипа), которое обычно может быть выражено как:
S <: T
выше
S
даT
подкласс , что означает, что когда вам нужноT
где значение типа,S
Значения типов тоже работают, как в КотлинеInt
даNumber
Подкласс:fun printNum(num: Number) { println(num) } >>> val n: Int = 1 >>> printNum(n) >>> 1 >>> printNum("I am a String") error: type mismatch: inferred type is String but Number was expected
-
Условно говоря,наследоватьУпор делается на своего рода «повторное использование реализации», а подтипирование — это отношение семантики типов, не имеющее ничего общего с реализацией. В Java мы, похоже, также можем достичь вышеуказанных отношений с помощью наследования классов:
class S extends class T
Поскольку отношение наследования также объявляется при объявлении отношения типа родитель-потомок, это обычно вызывает некоторую путаницу, но это не означает, что эти два понятия эквивалентны.
Несмотря на то чтоAny
иAny?
Кажется, что нет никакого отношения наследования, но когда нам нужно использоватьAny?
Там, где значение типа, очевидно, вы можете передать типAny
value, что не вызывает проблем при компиляции. Обратное не работает, например: тип параметраAny
функцию, мы передаем вAny?
Типnull
значение, возникает следующая ошибка:
error: null can not be a value of a non-null type Any
Из вышеизложенного также можно сделать предварительные выводы:Any
Значение можно заменить во всех случаяхAny?
значение, которое соответствует концепции «подтипирования».
Поэтому смело можем сказать:В системе типов КотлинаAny?
даAny
супертип и является корневым типом всех типов, хотя текущая документация официального сайта Kotlin не распространяется на это.
Любой? и Любой??
Один вопрос, который вы могли бы оспорить, заключается в том, еслиAny?
даAny
супертип , тоAny??
это сноваAny?
Супертип , если это правда, значит ли это, что нет так называемого «корневого типа всех типов»?
На самом деле типы, допускающие значение NULL, в Kotlin можно рассматривать как так называемыеUnion Type
, обычно используется в программеA | B
Представление, приближение объединения в математике. Если представлено объединением типовAny?
, что можно записать какAny ∪ Null
. соответствующийAny??
выражается какAny ∪ Null ∪ Null
, что эквивалентноAny ∪ Null
, Прямо сейчасAny??
ЭквивалентноAny?
. Поэтому, скажемAny?
Не проблема быть корневым типом всех типов.