日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

kotlin学习笔记——委托属性

發布時間:2024/4/15 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 kotlin学习笔记——委托属性 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

委托屬性

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接收一個類的引用和一個屬性的元數據,setValue多接收一個設置的值。 使用by關鍵字來委托屬性,如下: class Example {var p: String by Delegate() }

一、標準委托

kotlin標準庫中有一系列標準委托,我們可以直接使用,可以應付大部分情況。當然我們也可以自定義委托。

1、Lazy

需要提供一個lambda,當第一次執行getValue時會執行這個lambda進行初始化,之后再調用getValue會返回同一個值。所以委托的屬性可以延遲進行初始化,在真正使用前可以不必初始化。如: class App : Application{val database: SQLiteOpenHelper by lazy{MyDatabaseHelper(applicationContext)}override fun onCreate(){super.onCreate()var db = database.writableDatabase} } 所以只要當在onCreate中使用時才去初始化,而這時候applicationContext已經存在了。 lazy是線程安全的。如果不擔心多線程問題,可以使用lazy(LazyThreadSafeMode.NONE){ ... }來提高性能 同時要注意委托lazy的屬性必須是不可變變量,既val修飾,如果用var修飾會報編譯錯誤

2、Observable

這個委托會檢測值的變化,當屬性的set方法被調用,會自動執行我們指定的lambda表達式。一旦屬性被賦予了新值,我們就會接收到被委托的屬性、舊值和新值。如: class ViewModel(val db: MyDatabase){var name by Delegates.observable(""){d, old, new -> db.saveChange(this, new)} } 這個例子中一旦值被修改就會保存到數據庫中。 注意Delegates.observable("")中傳的是設定的初始值

3、Vetoable

這是一個特殊的Observable,通過指定的lambda表達式來確定是否保存新值。如 var name by Delegates.vetoable(0){d, old, new -> new >= 0 } 例子中表示只有新值是正數時才保存

4、NotNull

有時候使用屬性前可能未初始化,比如像activity這類無法在構造函數中初始化屬性的情況。通常我們會定義一個可為null的變量并初始化為空,在每次使用之前做判空。kotlin中還有另外一種方法,使用委托屬性NotNull,如: var name: String by Delegates.notNull() 如果賦值前使用時會拋出一個錯誤。 (目前這個方案與初始化為Null一樣都在使用前要進行判斷,否則拋出錯誤,所以不太能get到使用的點在哪里)

5、從Map中委托值

可以將屬性委托到一個map,屬性的值會從map中獲取,屬性的名字對應map中的key。 注意不同版本的區別 在有的版本中,需要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 ))

二、自定義委托

參照文章開始 自定義委托必須實現ReadWriteProperty或ReadOnlyProperty,取決于被委托對象是var還是val。 然后重寫setValue和getValue方法即可。 使用時可以直接使用(參考文章開始) 也可以像Delegates那樣集中定義函數,如: object DelegatesExt{fun notNullSingle<T>() : ReadWriteProperty<Any?, T> = NotNullSingle() //NotNullSingle是我們自定義的委托}

?

總結

以上是生活随笔為你收集整理的kotlin学习笔记——委托属性的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。