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
中的默认参数毫无意义,因为它总是被覆盖,并且我在所有调用函数中都复制了默认参数。那不是很干。
有没有更好的方法来传播默认参数?
答案 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
和/或foo2
,foo3
仅使用其参数,则进一步重构会将foo
和foo2
移至FooArgs
} class,产生与the answer by @nhaarman