仅在输入不为空时如何使用kotlin的默认参数?

时间:2019-05-16 16:23:37

标签: kotlin

示例:

data class Something(val mendatory: String = "default value")

val userInput: String? by SomeTypeOfInputFieldThatReturnsNullable

//val something = Something(userInput)    //not valid because userInput is String?

val something = if (userInput == null) 
                    Something() 
                else 
                    Something(userInput)

是否有一些更简单的方法来告诉Kotlin仅在参数不为null时传递参数?

3 个答案:

答案 0 :(得分:2)

取决于您的意思,而不是冗长。

一种方法是使用null-safe-operator (?.)和类似let的方法:

val something = userInput?.let(::Something) 
                         ?: Something()

由我决定是否真的不那么冗长。

另一种变体是基本上只将null值传递到data class。通过提供适当的构造函数或适当的工厂功能。以下只是许多变体之一(现在使用Companioninvoke):

data class Something(val mandatory: String) {
  companion object {
    operator fun invoke(s : String? = null) = Something( s ?: "default value")
  }
}

调用它就像:

val something = Something(userInput) // if userInput is String? the companion function is called... if it's String, the constructor is used

// or also using invoke:
val something = Something() // now with s = null, leading to "default value"

答案 1 :(得分:0)

我可以想到几种方法,但是所有方法都涉及到重复某处……

如果这是唯一需要默认值的地方,则可以将其移出类:

data class Something(val mandatory: String)

val something = Something(userInput ?: "default value")

或者您可以允许构造函数采用null —但是您需要将可为null的构造函数参数与non-null属性分开:

data class Something(mandatoryParam: String?) {
    val mandatory = mandatoryParam ?: "default value"
}

val something = Something(userInput)

或者Roland在他的答案中列出了一些选择:在决定调用哪个构造函数时,使用let可以避免某些重复。或在伴随对象上使用伪构造函数。

因此,没有一个明显的答案。 (我想我可能更喜欢上面介绍的两种方法之一,这取决于默认值是否以某种方式与该特定用户输入有关,或者无论构造对象时该默认值是否必须一定都适用。)

答案 2 :(得分:0)

有许多解决方案,其他已解释... 最好的是:

val something = userInput?.let(::Something) ?: Something()

但是如果将'val'更改为'var',还有另一种方法:

data class Something(var mendatory: String = "default value")

val userInput: String? by SomeTypeOfInputFieldThatReturnsNullable

val something = Something().apply { userInput?.let { mendatory = userInput } }