Kotlin: В каких ситуациях происходит неявное преобразование? - PullRequest
1 голос
/ 19 февраля 2020

Я новичок в Kotlin. Я наиболее знаком с Python, и я просто прочитал основы c Java Учебное пособие https://docs.oracle.com/javase/tutorial/java/index.html, прежде чем перейти к Kotlin.

У меня возник вопрос при чтении этого раздела документации Kotlin

https://kotlinlang.org/docs/reference/basic-types.html#explicit -конверсии

Что у меня есть из приведенного выше раздела документации:

  • Для присваиваний = происходит неявное преобразование типов. Если тип левой стороны является супертипом или типом правой стороны того же типа, код будет компилироваться. В противном случае это ошибка компиляции. В случае Int и Long они оба являются подтипами Number, но ни один из них не является подтипом друг друга, поэтому неявное преобразование не будет работать. Поэтому нам нужно использовать методы, такие как .toLong () или .toInt (), чтобы явно конвертировать их.

Затем, когда я читаю часть

val l = 1L + 3 // Long + Int => Long

Мне стало интересно, будет ли в этой ситуации происходить неявное преобразование типов.

В документации сказано, что это связано с перегрузкой операторов. Как эта перегрузка оператора реализована под капотом? Я пытался найти исходный код на Github https://github.com/JetBrains/kotlin/blob/master/core/builtins/native/kotlin/Primitives.kt, но здесь функции только объявлены, но не реализованы. Где я могу найти реализации?

Кажется, что перегрузка операций фактически не выполняет преобразование типов. Реализуем ли мы все возможные функции с одним и тем же именем, но с разными сигнатурами типов параметров, чтобы тип выводился, тогда выбирается функция с совпадающей сигнатурой?

И общий вопрос: в Kotlin точно в каких ситуациях происходит неявное преобразование?

1 Ответ

0 голосов
/ 19 февраля 2020

Для присваиваний = происходит неявное преобразование типов. Если тип левой стороны является супертипом или типом правой стороны того же типа, код будет компилироваться.

Назначения не являются особенными в этом. В более общем случае, если ожидаемый тип выражения является супертипом или совпадает с фактическим типом, код компилируется; просто ожидаемый тип для правой части присваивания является типом левой стороны. Я бы не сказал, что вставлено неявное преобразование, но я не думаю, что что-то ломается, если вы видите это таким образом.

Мы просто реализуем все возможные функции с тем же именем, но с другим типом параметра сигнатуры, так что тип выводится, тогда выбирается функция с совпадающей сигнатурой?

Да, именно (для этого случая). Если вы хотите поддерживать примитивные типы, вам необходимо обеспечить перегрузки для всех них.

Так что 1L + 3 - это просто вызов метода, если речь идет о синтаксическом анализе и проверке типов ( `Long .plus (Int): Long (в частности), неявное преобразование не используется. Но эти методы встроены в компилятор для специальной обработки, поэтому вы не видите реализацию.

Это становится двумя байт-кодом инструкциями i2l ("преобразовать int в длинную") и ladd ("добавить две длинных"), но это не то, что вам, вероятно, следует заботиться еще или долго.

И общий вопрос: в Kotlin, в каких именно случаях происходит неявное преобразование?

Smart броски - самые близкие Kotlin к неявным преобразованиям, но они достаточно отличаются от i. c .s в других языках, что я бы не использовал имя. Так что я бы сказал, никогда.

...