簡體   English   中英

即使支持字段可以為空,getter 也會返回不可為空的類型

[英]Having a getter return a non-nullable type even though the backing field is nullable

num設置時應該可以為空,但它返回的內容應該始終不可為空(具有默認值)。

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

即使返回值始終為非空,以下內容也不會編譯,這對我來說很有意義,因為類型不是推斷出來的,而是從支持字段中獲取的:

val a: Int = Test().num

類型不匹配:推斷的類型是 Int? 但 Int 是預期的

問題是如何將該 getter 的返回類型更改為不可為空? 如果我這樣做,編譯器會說:

Getter 返回類型必須等於屬性的類型,即“Int?”


我知道我可以用另一個屬性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

但這不是我想要的。 還有其他方法嗎?

var num: Int? = null

這是您的財產簽名。 如果您在內部確保不返回null值,則無關緊要。 簽名說,該值可以為空。

這意味着:

  • 您可以將null設置為此字段
  • 使用此字段的所有類必須處理屬性可以返回null的事實

第二個屬性的解決方案很好。

你當然可以用普通的舊java bean替換屬性,但我不建議這樣做,因為你必須使用getNumbsetNum訪問prop。

class Test {
    private var num: Int = 5

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

    fun getNum() = num
}

我不相信在Kotlin這是可能的。 您不能覆蓋get / set屬性的類型。 那么,如果您的房產是Int? 你將不得不返回一個Int? 並在使用它時檢查它是否為null

從技術上講,這是一項針對您所尋找的功能的要求 ,但它已經創建了多年。

您可以使用委托屬性實現此目的

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

請注意,此代碼不是線程安全的。 同樣使用此代碼示例,您無法為您的字段設置空值(因此無法返回默認值)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM