如何在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) } 

但现在我的默认参数是没有意义的,因为它总是overwriten,我已经在所有调用函数中重复默认参数。 这不是很干。

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

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

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

按照指导原则回答我自己的问题。


你可以做的是将调用函数中的参数声明为空,并使用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操作符中的一个来使用默认值。

 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和/或foo2foo3只使用它们的参数,那么进一步的重构会将foofoo2移动到FooArgs类中,从而得到类似的答案@nhaarman