看例子代码,学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}")
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章