Для присваиваний = происходит неявное преобразование типов. Если тип левой стороны является супертипом или типом правой стороны того же типа, код будет компилироваться.
Назначения не являются особенными в этом. В более общем случае, если ожидаемый тип выражения является супертипом или совпадает с фактическим типом, код компилируется; просто ожидаемый тип для правой части присваивания является типом левой стороны. Я бы не сказал, что вставлено неявное преобразование, но я не думаю, что что-то ломается, если вы видите это таким образом.
Мы просто реализуем все возможные функции с тем же именем, но с другим типом параметра сигнатуры, так что тип выводится, тогда выбирается функция с совпадающей сигнатурой?
Да, именно (для этого случая). Если вы хотите поддерживать примитивные типы, вам необходимо обеспечить перегрузки для всех них.
Так что 1L + 3
- это просто вызов метода, если речь идет о синтаксическом анализе и проверке типов ( `Long .plus (Int): Long (в частности), неявное преобразование не используется. Но эти методы встроены в компилятор для специальной обработки, поэтому вы не видите реализацию.
Это становится двумя байт-кодом инструкциями i2l
("преобразовать int в длинную") и ladd
("добавить две длинных"), но это не то, что вам, вероятно, следует заботиться еще или долго.
И общий вопрос: в Kotlin, в каких именно случаях происходит неявное преобразование?
Smart броски - самые близкие Kotlin к неявным преобразованиям, но они достаточно отличаются от i. c .s в других языках, что я бы не использовал имя. Так что я бы сказал, никогда.