Kotlin 当传递null时,是否有方法在非可选参数上使用默认值?
例如,如果我有以下数据类:Kotlin 当传递null时,是否有方法在非可选参数上使用默认值?,kotlin,nullable,default-parameters,Kotlin,Nullable,Default Parameters,例如,如果我有以下数据类: data class Data( val name: String = "", val number: Long = 0 ) 以及可以返回null的函数: fun newName(): String? {} fun newNumber(): Long? {} val newName = newName() val newNumber = newNumber() val data = Data( if (newName != nu
data class Data(
val name: String = "",
val number: Long = 0
)
以及可以返回null
的函数:
fun newName(): String? {}
fun newNumber(): Long? {}
val newName = newName()
val newNumber = newNumber()
val data = Data(
if (newName != null) newName else "",
if (newNumber != null) newNumber else 0
)
我知道,如果函数的值不是null
,我可以使用以下值:
fun newName(): String? {}
fun newNumber(): Long? {}
val newName = newName()
val newNumber = newNumber()
val data = Data(
if (newName != null) newName else "",
if (newNumber != null) newNumber else 0
)
但是,当值为null
时,是否有方法仅使用Data
类的构造函数中指定的默认值
我在文档中找不到任何东西,但我希望类似的东西能起作用:
val data = Data(newName()?, newNumber()?)
但这不会编译。当传递null
时,您可以为您的数据类和其定义一个默认值:
data class Data private constructor(
val name: String,
val number: Long
) {
companion object {
operator fun invoke(
name: String? = null,
number: Long? = null
) = Data(
name ?: "",
number ?: 0
)
}
}
辅助构造函数仅支持可为null的基元属性。这意味着如果属性不是基元类型,它将产生两个相同的构造函数,例如:
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)
}
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
}
另一种方法是使用invoke
运算符,例如:
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)
}
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 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)
}
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
}
如果(newName!=null)newName else“”,您可以使用
newName?:“”
,而不是if(newName!=null)newName else“”
。这叫猫王接线员。@Mibac哦,对了,我忘了!当然更简洁,但它仍然没有使用类构造函数中定义的默认参数。哦,这是一个很好的解决方法!尽管如此,我还是希望语言中能有这样的东西;如果只是为了摆脱样板文件。如果所有第二个属性(编号)都被删除,它会起作用吗?我收到数据类数据(val name:String=”“){constructor(name:String?=null)的编译错误:this(name?:“”)}
我认为您必须传入null
或添加另一个辅助构造函数。e、 g.constructor():这个(“”)
@eendroy我意识到这个重载解析歧义是可以避免的,我已经更新了我的答案accordingly@eendroroy您是对的,我发现在这两种情况下使用带有invoke操作符的伴随对象都应该有效,我已经相应地更新了我的答案;i、 e.现在它将在没有number:Long
的情况下工作,并且只保留name:String