Есть ли способ использовать значение по умолчанию для необязательного параметра, когда передается значение NULL?
Например, если у меня есть следующий класс данных:
data class Data(
val name: String = "",
val number: Long = 0
)
И функции, которые могут вернуть null
:
fun newName(): String? {}
fun newNumber(): Long? {}
Я знаю, что могу использовать следующее, чтобы использовать значение функций, если они не null
:
val newName = newName()
val newNumber = newNumber()
val data = Data(
if (newName != null) newName else "",
if (newNumber != null) newNumber else 0
)
Но есть ли способ просто использовать значение по умолчанию, указанное в конструкторе Data
класс, когда значения null
?
Я не мог найти ничего в документации, но я надеялся, что что-то вроде этого будет работать:
val data = Data(newName()?, newNumber()?)
Но это не компилируется.
3 ответа
Вы можете создать вторичный конструктор, который использует те же значения по умолчанию при получении null
:
data class Data(
val name: String = "",
val number: Long = 0
) {
constructor(
name: String? = null,
number: Long? = null
) : this(
name ?: "",
number ?: 0
)
}
Вторичный конструктор поддерживает только примитивные свойства Nullable. это означает, что это приведет к 2 одинаковым конструкторам, если свойство не является примитивным типом, например:
data class Data(val name: String) {
constructor(name: String? = null) : this(name ?: "foo");
// ^--- report constructor signature error
}
data class Data(val number: Long = 0) {
constructor(number: Long? = null) : this(number ?: 0)
// ^--- No problem since there are 2 constructors generated:
// Data(long number) and Data(java.lang.Long number)
}
альтернативный способ использует invoke
оператор для этого, например:
data class Data(val name: String) {
companion object {
operator fun invoke(name: String? = null) = Data(name ?: "")
}
}
Если класс не является классом данных, то вы можете лениво инициализировать свойства из параметров, а не определять свойства в основном конструкторе, например:
class Data(name: String? = null, number: Long? = null) {
val name = name ?: ""
val number = number ?: 0
}
Если нужно, могу предложить другое решение:
data class Data(
val inputName: String?,
val inputNumber: Long?
) {
private val name = inputName ?: ""
private val number = inputNumber ?: 0
}