Intereting Posts
Kotlin: Как получить и установить текст в TextView на Android с помощью Kotlin? Как «Список <MyClass> :: clas.java` в kotlin Как я могу избежать нулевых свойств в Котлине Android: получить DAO в ViewModel Широковещательный приемник onReceive () не вызывается Corda: error = org.hibernate.InstantiationException: конструктор по умолчанию для объекта Свойства Kotlin не могут быть переопределены с помощью subinterface Kotlin \ Java – Строка типа "$ 1" на номер Как создать экземпляр Singleton только один раз в моем приложении и его библиотеках? Не удается профилировать приложение Android в Android Studio Переменные не инициализируются должным образом при инициализации в абстрактной абстрактной функции, вызванной из конструктора или блока init Исправленная строка Kotlin вызывает пустую ошибку Могу ли я обеспечить нулевую безопасность для типов платформ из Java API? Kotlin – Прерывистая ошибка «плохого файла класса» Создание нового каталога с использованием Kotlin, Mkdir () не работает

Как распространять аргументы по умолчанию между функциями в 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 бессмыслен, поскольку он всегда перезаписывается, и я дублировал аргументы по умолчанию во всех вызывающих функциях. Это не очень СУХОЙ.

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

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

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

 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