kotlin学习笔记——委托属性
生活随笔
收集整理的這篇文章主要介紹了
kotlin学习笔记——委托属性
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
委托屬性
kotlin提供了將屬性委托到一個類的方法,就是委托屬性。 當我們使用屬性的get和set方法時,屬性委托的getValue和setValue就會被調用。 屬性委托的結構如下: class Delegate<T> : ReadWriteProperty<Any?, T>{override fun getValue(thisRef: Any?, property: KProperty<*>): T{return ...}override fun setValue(thisRef: Any?, property: KProperty<*>, value: T){...} } 其中T是委托屬性的類型,getValue接收一個類的引用和一個屬性的元數(shù)據(jù),setValue多接收一個設置的值。 使用by關鍵字來委托屬性,如下: class Example {var p: String by Delegate() }一、標準委托
kotlin標準庫中有一系列標準委托,我們可以直接使用,可以應付大部分情況。當然我們也可以自定義委托。1、Lazy
需要提供一個lambda,當?shù)谝淮螆?zhí)行getValue時會執(zhí)行這個lambda進行初始化,之后再調用getValue會返回同一個值。所以委托的屬性可以延遲進行初始化,在真正使用前可以不必初始化。如: class App : Application{val database: SQLiteOpenHelper by lazy{MyDatabaseHelper(applicationContext)}override fun onCreate(){super.onCreate()var db = database.writableDatabase} } 所以只要當在onCreate中使用時才去初始化,而這時候applicationContext已經(jīng)存在了。 lazy是線程安全的。如果不擔心多線程問題,可以使用lazy(LazyThreadSafeMode.NONE){ ... }來提高性能 同時要注意委托l(wèi)azy的屬性必須是不可變變量,既val修飾,如果用var修飾會報編譯錯誤。2、Observable
這個委托會檢測值的變化,當屬性的set方法被調用,會自動執(zhí)行我們指定的lambda表達式。一旦屬性被賦予了新值,我們就會接收到被委托的屬性、舊值和新值。如: class ViewModel(val db: MyDatabase){var name by Delegates.observable(""){d, old, new -> db.saveChange(this, new)} } 這個例子中一旦值被修改就會保存到數(shù)據(jù)庫中。 注意Delegates.observable("")中傳的是設定的初始值3、Vetoable
這是一個特殊的Observable,通過指定的lambda表達式來確定是否保存新值。如 var name by Delegates.vetoable(0){d, old, new -> new >= 0 } 例子中表示只有新值是正數(shù)時才保存4、NotNull
有時候使用屬性前可能未初始化,比如像activity這類無法在構造函數(shù)中初始化屬性的情況。通常我們會定義一個可為null的變量并初始化為空,在每次使用之前做判空。kotlin中還有另外一種方法,使用委托屬性NotNull,如: var name: String by Delegates.notNull() 如果賦值前使用時會拋出一個錯誤。 (目前這個方案與初始化為Null一樣都在使用前要進行判斷,否則拋出錯誤,所以不太能get到使用的點在哪里)5、從Map中委托值
可以將屬性委托到一個map,屬性的值會從map中獲取,屬性的名字對應map中的key。 注意不同版本的區(qū)別 在有的版本中,需要import kotlin.properties.getValue 或 kotlin.properties.setValue 在kotlin-stdlib:1.1.2-4中則不需要,但是不能直接使用map,如: class Config (map: HashMap<String, Any?>){var name: String by mapvar id: Int by map }var config = Config(hashMapOf("name" to "test","id" to 12 ))二、自定義委托
參照文章開始 自定義委托必須實現(xiàn)ReadWriteProperty或ReadOnlyProperty,取決于被委托對象是var還是val。 然后重寫setValue和getValue方法即可。 使用時可以直接使用(參考文章開始) 也可以像Delegates那樣集中定義函數(shù),如: object DelegatesExt{fun notNullSingle<T>() : ReadWriteProperty<Any?, T> = NotNullSingle() //NotNullSingle是我們自定義的委托}?
總結
以上是生活随笔為你收集整理的kotlin学习笔记——委托属性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kotlin学习笔记——Kotlin A
- 下一篇: kotlin学习笔记——sqlite(a