2017-06-23 18 views
10

例如,如果我有以下数据类:当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 
) 

但是,有没有办法只有用在CON指定的默认值当值为null时,Data类的结构体?

我找不到文档中任何东西,但我希望像这样的工作:

val data = Data(newName()?, newNumber()?) 

但是,这并不编译。

+0

而不是'if(newName!= null)newName else“”''你可以使用'newName?:'“''。这就是所谓的猫王操作员。 – Mibac

+0

@Mibac哦,对了,我忘了!绝对更简洁,但它仍不使用类构造函数中定义的默认参数。 – Bryan

回答

5

可以创建接收null当使用相同的默认值的secondary constructor

data class Data(
     val name: String = "", 
     val number: Long = 0 
) { 
    constructor(
      name: String? = null, 
      number: Long? = null 
    ) : this(
      name ?: "", 
      number ?: 0 
    ) 
} 
+0

哦,这是一个很好的解决方法!但是,这让我希望这样的东西被植入语言中;如果只是为了摆脱样板。 – Bryan

4

二次构造仅支持用于可空原语的属性。这意味着它将导致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 
} 
相关问题