たとえば、次のデータクラスがある場合:
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()?)
しかし、それはコンパイルされません。
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 ?: "")
}
}
[〜#〜] if [〜#〜]クラスはデータクラスではないため、プライマリコンストラクターでプロパティを定義するのではなく、パラメーターからプロパティを遅延初期化できます。次に例を示します。
class Data(name: String? = null, number: Long? = null) {
val name = name ?: ""
val number = number ?: 0
}