參考文章: https://kotlinlang.org/docs/reference/delegated-properties.html
針對類型裡的特性(propertys), 常數(val)的特性內定 getter 是用 get( ) 方法去讀取主角(field)的值, 對於可寫入的特性(var)而言, 內定 setter 則用 set(v: Type) 方法設定幕後的主角(field), 除非要另外處理 field 的運算才需改寫, 否則 kotlin 會自動加上必要程式碼:
class SomeClass {
var v: String = "?"
// get( ) { return field }
// set(s:String) { field = s }
val readonly: Int = 0
// get( ) { return field }
}
物件在引用特性時不必後綴成對小括號, 因此很簡潔. 物件引用方法( ) 時可以看做是一個運算的結果, 也就是所謂的函數. Kotlin 針對特性或變數有個特別條款可以用 by 跑龍套, 也就是說留待跑龍套代為處置, Koltin 已經為跑龍套主角(object)指定了兩個運算 operator getValue( ) 及 operator setValue( ) 來處理特性或變數的讀寫機制, 若想改寫,可以 import pacage 針對讀與寫操作分別作運算,其中對應 get( ) 方法就是 operator getValue( ), 對應 set( ) 方法就是 operator setValue( ), 詳如範例:
import kotlin.reflect.*
class InitString (str: String) { // 代理的主角類型
var bakendField: String = str // 真正被讀寫的幕後主角
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
print(property.name + " : ")
return bakendField // return value for method get( ), 讀取
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, v: String) {
println(property.name + " = " + v)
bakendField = v // set value to property for method set(v), 寫入
}
}
fun main(){
var c : String by InitString("???") // 用物件 InitString( ) 代理改寫變數的讀/寫機制
println(c) // 讀取變數 c
c = "dd" // 設定變數 c
println(c) // 重新讀取變數 c
}
執行結果:
c : ???
c = dd
c : dd
沒有留言:
張貼留言