如何在Kotlin中的函数之间传播默认参数?

时间:2016-11-21 12:36:23

标签: kotlin

Kotlin有default arguments for function and constructor parameters。现在,我有一个功能

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中的默认参数毫无意义,因为它总是被覆盖,并且我在所有调用函数中都复制了默认参数。那不是很干。

有没有更好的方法来传播默认参数?

3 个答案:

答案 0 :(得分:2)

不是让三个函数具有相同的默认参数:

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()
  }
}

答案 1 :(得分:1)

the guidelines的鼓励下回答我自己的问题。

您可以做的是将调用函数中的参数声明为可为空并使用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)
}

然后,在提供null时,使用其中一个elvis operator来使用默认值。

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)
    }
}

答案 2 :(得分:0)

如果你有多个函数使用相同的参数(具有相同的默认值),那么这是一个代码气味,表明这些参数密切相关,应该存在于自己的类中。

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和/或foo2foo3仅使用其参数,则进一步重构会将foofoo2移至FooArgs } class,产生与the answer by @nhaarman

类似的解决方案