Intereting Posts
UNRESOLVED_REFERENCE в виджетах (TextView) разрешен элемент ошибки в android-kotlin Гарантирован порядок вызовов внутри конструктора DigestUtils.md5Hex () генерирует неправильное значение хэша при передаче объекта String kotlin-js конвертировать строку в другую кодировку Создание карты со значениями, содержащими дженерики Как написать надлежащий тест для реактивного репозитория интерфейса, который возвращает Observable только в том случае, когда есть какое-то событие, как издеваться над запуском этого события Android – добавьте UNDO SnackBar для прокрутки, чтобы удалить Неудачные тесты котлинских модулей после плагина 3.0 Почему этот класс считается окончательным? IOException: AsyncTask Image Загрузить Kotlin Android (дескриптор Bad File) время подключения: подключиться к журналу IDE Spring Data JPA Как использовать ноль Kotlin вместо необязательного Не удается отправить многостраничные данные / данные формы с помощью Volley Использование с автоклином в Котлине Kotlin – Как сделать поле только для чтения для внешних классов

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

У Kotlin есть аргументы по умолчанию для параметров функции и конструктора . Теперь у меня есть функция

fun foo(bar: String = "ABC", baz: Int = 42) {} 

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

Я знаю, я могу объявить аргументы по умолчанию в вызывающих функциях

 fun foo2(bar: String = "ABC", baz: Int = 42) { // do stuff foo(bar, baz) } fun foo3(bar: String = "ABC", baz: Int = 42) { // do other stuff foo(bar, baz) } 

но теперь мой параметр по умолчанию в foo бессмыслен, поскольку он всегда перезаписывается, и я дублировал аргументы по умолчанию во всех вызывающих функциях. Это не очень СУХОЙ.

Есть ли лучший способ распространения аргументов по умолчанию?

Вместо трех функций с одинаковыми аргументами по умолчанию:

 fun foo(bar: String = "ABC", baz: Int = 42) fun foo2(bar: String = "ABC", baz: Int = 42) fun foo3(bar: String = "ABC", baz: Int = 42) 

Создайте класс-оболочку, который принимает аргументы и имеет функции без параметров:

 class Foo(val bar: String = "ABC", val baz: Int = 42) { fun foo() { /* ... */ } fun foo2() { // ... foo() } fun foo3() { // ... foo() } } 

Отвечая на мой собственный вопрос, в соответствии с рекомендациями .


Что вы можете сделать, объявить параметры в вызывающих функциях как nullable и использовать null в качестве аргумента по умолчанию:

 fun foo2(bar: String? = null: Int? = null) { // do stuff foo(bar, baz) } fun foo3(bar: String? = null, baz: Int? = null) { // do other stuff foo(bar, baz) } 

Затем используйте один из операторов elvis для использования значений по умолчанию, когда предоставляется null .

 fun foo(bar: String? = null, baz: Int? = null) { val realBar = bar ?: "ABC" val realBaz = baz ?: 42 } 

Если вы работаете с классом вместо функции, вы можете вытащить свойство конструктора и присвоить ему значение по умолчанию:

 class Foo(bar: String? = null, baz: Int? = null) { val bar = bar ?: "ABC" val baz = baz ?: 42 } 

В качестве альтернативы, скажем, если ваш класс является классом data class и вы хотите иметь свойства в основном конструкторе, вы можете объявить фабричный метод для обработки значений по умолчанию:

 class Foo(val bar: String, baz: Int) { companion object { fun create(bar: String? = null, baz: Int? = null) = Foo(bar ?: "ABC", baz ?: 42) } } 

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

 data class FooArgs( val bar: String = "ABC", val baz: Int = 42 ) fun foo( args: FooArgs = FooArgs() ) { /* ... */} fun foo2( args: FooArgs = FooArgs() ) { ... foo(args) } fun foo3( args: FooArgs = FooArgs() ) { ... foo(args) } 

Если foo и / или foo2 , foo3 используют только свои аргументы, то дальнейший рефакторинг переместит foo и foo2 в класс FooArgs , что приведет к аналогичному решению ответа от @nhaarman