ПрограммированиеAndroid разработчик

Как работают default arguments и named parameters в Kotlin? Расскажите об отличиях от Java, нюансах передачи аргументов, компиляции с overload-методами, порядке именованных и позиционных параметров. Приведите пример.

Проходите собеседования с ИИ помощником Hintsage

Ответ.

Kotlin поддерживает значения по умолчанию (default arguments) и именованные параметры (named parameters), что дает большую гибкость по сравнению с Java.

Основные моменты:

  • В Kotlin параметры функции могут иметь значения по умолчанию:
    fun greet(name: String = "User", greeting: String = "Hello") { println("$greeting, $name!") }
  • Можно вызывать функцию с указанием только нужных параметров — остальные заполнятся по умолчанию.
  • Именованные параметры позволяют явно указывать имя аргумента — особенно удобно, когда у функции много параметров:
    greet(greeting = "Привет") // -> Привет, User!
  • Можно комбинировать обычные (позиционные) и именованные параметры, пока именованные не используются в середине вызова.
  • В отличие от Java (где делают overload для каждой комбинации), Kotlin компилирует default-arguments в overload-методы только для interop с Java, а внутри Kotlin этого не видно.

Нюансы:

  • После использования именованного аргумента следующие аргументы должны быть также именованными.
  • Для использования функций с default-параметрами из Java могут потребоваться аннотации @JvmOverloads.

Вопрос с подвохом.

Можно ли смешивать позиционные и именованные аргументы в любом порядке при вызове функции в Kotlin?

Правильный ответ: Нет, после того как вы указали хотя бы один именованный аргумент, все последующие должны быть именованными. Нарушение вызовет ошибку компиляции.

// Неверно greet(greeting = "Hi", "Ivan") // Ошибка! // Верно greet("Ivan", greeting = "Hi") greet(name = "Ivan", greeting = "Hi")

Примеры реальных ошибок из-за незнания тонкостей темы.


История

Команда интегрировала Kotlin-модуль с legacy Java-проектом и забыла добавить аннотацию @JvmOverloads для функции с default-параметрами. В результате Java-код не видел необходимых overload-методов — возникали runtime ошибки при вызове.


История

При рефакторинге с использованием именованных параметров разработчик случайно переставил местами аргументы — при дальнейшей смене названий параметров это прошло незамеченно (типизация не нарушена, но семантика вызова изменилась!). Это привело к странным багам в логике UI, обнаружили не сразу.


История

Один из разработчиков в попытке повысить читабельность смешал позиционные и именованные аргументы в середине вызова. Код не компилировался, но команда с трудом поняла, в чем именно проблема — т.к. часто встречали это в других языках и ожидали аналогичного поведения от Kotlin.