即使支持字段可以为空,使getter返回非可空类型

时间:2017-10-06 13:09:24

标签: kotlin nullable getter non-nullable

num在设置时应该可以为空,但它返回的内容应该始终是不可为空的(具有默认值)。

class Test {
    var num: Int? = null
        get() = field ?: 5 // default value if null
}

以下版本无法编译,即使返回的值始终为非null,这对我来说也是有意义的,因为该类型不是推断的,而是来自支持字段:

val a: Int = Test().num
  

类型不匹配:推断类型是Int?但Int预计

问题是如何将该getter的返回类型更改为不可为空?如果我这样做,编译器会说:

  

Getter返回类型必须等于属性的类型,即   '诠释'?

我知道我可以用另一个属性numNotNullable解决它(没有支持字段)。

class Test {
    var num: Int? = null
        get() = field ?: 5 // default value if null

    val numNotNullable: Int
        get() = num ?: 5
}

val c: Int = Test().numNotNullable

但这不是我想要的。 还有其他办法吗?

3 个答案:

答案 0 :(得分:5)

var num: Int? = null

这是您的财产签名。如果您在内部确保不返回null值,则无关紧要。签名说,该值可以为空。

这意味着:

  • 您可以将null设置为此字段
  • 使用此字段的所有类必须处理属性可以返回null
  • 的事实

使用第二个属性的解决方案很好。

您当然可以使用普通的旧java bean替换该属性,但我不建议这样做,因为您必须使用getNumbsetNum访问道具。

class Test {
    private var num: Int = 5

    fun setNum(num: Int?) {
        this.num = num ?: 5
    }

    fun getNum() = num
}

答案 1 :(得分:3)

我认为Kotlin不可能这样做。您不能覆盖get / set属性的类型。因此,如果您的属性为Int?,那么您将不得不返回null并在使用时检查它是否为DECLARE @CandidateNumber INT SET @CandidateNumber = 5921368 UPDATE XXX SET @CandidateNumber = CandidateNumber = @CandidateNumber + 1 GO

从技术上来说,你需要的是feature request,但它已经存在多年了。

答案 2 :(得分:0)

您可以使用 delegated properties

import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty

class LazyVar<T : Any>(private var initializer: () -> T) : ReadWriteProperty<Any?, T> {
    private var value: T? = null

    override fun getValue(thisRef: Any?, property: KProperty<*>): T {
        if (value == null) {
            value = initializer()
            print(value)
        }
        return value as T
    }

    override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        this.value = value
    }
}

class Test {
    var num: Int by LazyVar { 5 }
}

val a: Int = Test().num

请注意,此代码不是线程安全的。同样使用此代码示例,您无法为您的字段设置空值(因此无法恢复默认值)。