首页 文章

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

提问于
浏览
5

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 回答

  • 1

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

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

    在准则的鼓励下回答我自己的问题 .


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

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

    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 类中,从而产生类似于the answer by @nhaarman的解决方案

相关问题