看例子代碼,學kotlin語法(1.4)(委託 : by)

kotlin學習相關鏈接
在線學習
Kotlin 官方文檔
中文站(更新到 1.1):https://www.kotlincn.net/
網址(更新到 1.0.3):http://tanfujun.com/kotlin-web-site-cn/
Kotlin 中文論壇:https://www.kotliner.cn/
《Kotlin for android developers》中文版翻譯
語言學習網址:RUNOOB備註:裏面的虛擬機模擬適合小demo調試,程序太大還是建議到AS中。

1、屬性委託

/**
 * 新語法: var 屬性名稱: 類型by 表達式()
 * by之後的表達式是委託,因爲默認具有get()與set()方法
 * 與屬性相對應的將被委派給他
 * 屬性委託不需要實現任何接口,但是他們必須提供getValue()與setValue()方法
 */

import kotlin.reflect.KProperty

class Example {
    var p: String by Delegate() //字符串變量p 委託 Delegate()

    override fun toString() = "Example Class"
}

class Delegate() {
    operator fun getValue(thisRef: Any?, prop: KProperty<*>): String {
        return "$thisRef, thank you for delegating '${prop.name}' to me!"
    }

    operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: String) {
        println("$value has been assigned to ${prop.name} in $thisRef")
    }
}

fun main(args: Array<String>) {
    val e = Example()
    println(e.p)
    e.p = "NEW"
}

2、Delegate

/**
 * Delegates.lazy() 最終返回懶惰函數的屬性
 * 第一次調用get(),會執行傳遞給lazy()的lambda 表達式作爲參數,並記住結果
 * 隨後用get()返回記住的結果
 * 如果你想要線程安全。可以改用blockingLazy(),他可以確保值在一個線程中使用
 */

class LazySample {
    val lazy: String by lazy {
        println("computed!")
        "my lazy"
    }
}

fun main(args: Array<String>) {
    val sample = LazySample()
    println("lazy = ${sample.lazy}")
    println("lazy = ${sample.lazy}")
}

3、observable觀察者

/**
 * observable() 函數有兩個參數:初始值和用於修改的處理程序
 * 每當我們分配給‘name’時候 ,處理程序都會被調用,它具有三個參數
 * 分配的屬性,舊值,新值
 * 分配使用的是vetoable()而不是observable().
 */
import kotlin.properties.Delegates

class User {
    var name: String by Delegates.observable("no name") {
        d, old, new ->
        println("$old - $new")
    }
}

fun main(args: Array<String>) {
    val user = User()
    user.name = "Carl"
}

4、抽象屬性 設置爲非null

/**
 * kotlin不能有未初始化的的非抽象屬性,你可以初始化爲null
 * 但是每次訪問都必須進行檢查
 * 需要在寫入屬性之後進行讀取,否則會有異常
 * 當var變量爲非null時,需要在構造函數中爲其分配適當的值
 */

import kotlin.properties.Delegates

class User {
    var name: String by Delegates.notNull()

    fun init(name: String) {
        this.name = name
    }
}

fun main(args: Array<String>) {
    val user = User()
    // user.name -> IllegalStateException
    user.init("Carl")
    println(user.name)
}

5、map的屬性

/**
 * 當屬性存儲在map中,在解析JSON時會引發一些問題
 * 我們應該調通過key-屬性名稱 或者var分配時候修改地圖  來獲取map值
 */

class User(val map: Map<String, Any?>) {
    val name: String by map
    val age: Int     by map
}

fun main(args: Array<String>) {
    val user = User(mapOf(
            "name" to "John Doe",
            "age"  to 25
    ))

    println("name = ${user.name}, age = ${user.age}")
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章