Intereting Posts
Типы соединений / интерфейсы расширения IllegalStateException: активность была уничтожена (уровень API <21) Тонкий diff при запуске в intellij и выполнении jar Как скомпилировать код Kotlin-JS с сопрограммами? Можно ли избежать повторения кода, когда объект должен вернуть измененную копию самого себя? Требуется функция Котлина Нет, но определяется как другой тип Kotlin + Кинжал – введите карту для фабрики ViewModel Когда у меня есть выбранный вид и сдвигается вниз по строке состояния, когда я поднимаю его снова, вид не выбран Как перенести карту в андроид с помощью Kotlin Каково место в иерархии типов типов с возможностью NULL? как конвертировать дату UTC в местное время GMT на Android Ошибка ': android: transformKotlinClassesWithJillForDebug'. При создании приложения для Android, написанного в Kotlin + LibGDX Как получить доступ к атрибутам / методам в стандартном параметре класса Свадьба для Котлина firebase db: модели с переданными свойствами Котлина

Как распространять аргументы по умолчанию между функциями в 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