2017-02-09 41 views
3

這些是否相等?Kotlin只讀屬性有和沒有吸氣器

  • val foo = someFooReturningFunction()

  • val foo get() = someFooReturningFunction()

我明白他們的文檔的方式,但在我自己的測試,他們都沒有。

使用get()someFooReturningFunction()每次訪問屬性時都會被評估,而不是隻評估一次。

回答

4

它們不等價。自定義獲取器確實在每次訪問屬性時評估,類似於普通函數,而沒有自定義訪問器的val屬性僅在初始化時評估一次(實際上存儲在JVM平臺上的final字段中)。

這裏有至少幾個區別:

  • 控制流分析和爲空推理需要考慮它,如果酒店有定製的吸附材料(或者是open,因此可能與自定義覆蓋吸氣劑),因爲不能保證該屬性返回上連續調用相同的值:

    if (someObject.defaultGetterProperty != null) { 
        someObject.defaultGetterProperty.let { println(it) } // OK 
    } 
    

    if (someObject.propertyWithCustomGetter != null) { 
        someObject.propertyWithCustomGetter { println(it) } // Error: cannot smart-cast 
    } 
    
  • 當屬性是private,如果它沒有定製吸氣劑則完全不產生吸氣劑和背襯字段被直接訪問。然而,這是一個實現細節,不是依賴的東西。

0

不是。除了@ hotkey的原因,這裏有一個簡單的演示,使用可變屬性顯示它們何時絕對不等價。 TLDR:如果您的財產是使用可變屬性計算的,則始終在初始化程序上使用自定義getter。

data class Calculation(val value1: Int, var value2: Int) { 
    val sum: Int = value1 + value2 
    val sumWithGetter: Int 
     get() = value1 + value2 
} 

val calculation = Calculation(1, 2) 
println(calculation.sumWithGetter) // prints 3 
println(calculation.sum)   // prints 3 

calculation.value2 = 0 
println(calculation.sumWithGetter) // prints 1 (correct) 
println(calculation.sum)   // prints 3!