Как использовать параметр по умолчанию Kotlin, только если вход не является нулевым? - PullRequest
0 голосов
/ 16 мая 2019

Пример:

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 только о передаче параметра, если он не нулевой?

Ответы [ 3 ]

2 голосов
/ 16 мая 2019

Зависит от того, что вы подразумеваете под менее многословным.

Одним из способов является использование нулевого безопасного оператора (?.) и что-то вроде let:

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

Я оставляю на ваше усмотрение, действительно ли это менее многословно.

Другой вариант - просто передать значение null до data class. Либо предоставляя соответствующие конструкторы, либо имея соответствующие фабричные функции. Ниже приведен только один из многих вариантов (теперь используются Companion и invoke):

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"
0 голосов
/ 17 мая 2019

Есть много решений, которые другие объяснили ... Лучший из них:

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 } }
0 голосов
/ 16 мая 2019

Я могу придумать несколько подходов, но все они где-то повторяются…

Если это единственное место, где вам нужно значение по умолчанию, вы можете переместить его из класса:

data class Something(val mandatory: String)

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

Или вы можете позволить конструктору принимать значение NULL - но тогда вам нужно отделить обнуляемый параметр конструктора от ненулевого свойства:

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

val something = Something(userInput)

Или есть варианты, которые Роланд изложил в своем ответе: используйте let, чтобы избежать некоторых повторений при принятии решения, какой конструктор вызывать; или используя псевдо-конструктор для объекта-компаньона.

Итак, нет однозначного ответа (Думаю, я бы предпочел один из двух подходов, которые я проиллюстрировал, в зависимости от того, относится ли значение по умолчанию каким-либо образом к этому конкретному пользовательскому вводу или оно обязательно должно применяться, как бы объект не создавался.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...