当一个参数是类时,使用默认值初始化类

时间:2018-10-15 07:08:45

标签: kotlin

kotlin 1.2.60

我有以下数据类,我想用默认值初始化它们。但是,我不确定如何将硬盘初始化为类。

我尝试执行以下操作,但这将创建一个新的HeadDisk对象,而不是我想要的东西:

data class HeadDisk(var size: Float,
                    var manufacturer: Manufacturer)

data class Computer(var speed: Float = 0F,
                    var screenSize: Float = 0F,
                    var hardDisk: HeadDisk = HeadDisk())

我可以通过将其显式设置为null值来将其设置为null。但我不想将其显式设置为null。

data class Computer(var speed: Float = 0F,
                    var screenSize: Float = 0F,
                    var hardDisk: HeadDisk? = null)

或者对委托执行以下操作:

data class Computer(var speed: Float = 0F,
                    var screenSize: Float = 0F) {

    var hardDisk: HeadDisk by Delegates.notNull()
}

只是想知道什么是最好和最简单的解决方案?

2 个答案:

答案 0 :(得分:2)

我认为您的假设不正确。使用

data class Computer(var speed: Float = 0F,
                    var screenSize: Float = 0F,
                    var hardDisk: HeadDisk = HeadDisk())

除非需要,否则不会创建默认的HeadDisk()。生成的Java代码

class Foo
class Bar(val foo: Foo = Foo())

// $FF: synthetic method
public Bar(Foo var1, int var2, DefaultConstructorMarker var3) {
   if ((var2 & 1) != 0) { // this checks whether you called it with or without that parameter
      var1 = new Foo(); // a new one each time
   }
   this(var1);
}

答案 1 :(得分:1)

我想您应该在这里使用null object pattern,因为在构造函数中不支持委托和lateinit vars。我通常要做的是这样的:

//简单示例

class Foo(val bar: String = NO_BAR) {

    // note the instance equality check
    fun hasBar() = bar !== NO_BAR

    companion object {

        val NO_BAR = UUID.randomUUID().toString()
    }
}

所以我有一个val代表has no value状态。

另一种解决方案是使用Arrow中的OptionalOption数据类型