标准委托

1.惰性加载

拉远站是一个函数,接受一个lambda表达式座位参数初始化函数,与前面实现的delegate类似,返回一个Lazy类型的实例,这个实例可以座位委托实现懒加载属性:
第一次调用get的时候,将会执行从lazy函数传入Lambda表达式,然后会记住这次执行的结果,以后所有对get()的调用都只会简单地返回以前记住的结果。

//  标准委托:惰性委托(lazy)
val lazyValue: String by lazy {
    println("computed")
    "hello"
}

fun main(args: Array<String>)
{
    println(lazyValue)
    println(lazyValue)
}

输出:

这里写图片描述

在默认情况下,惰性加载是执行同步的(synchronized)。属性值只在唯一一个线程内执行,然后所有线程都将得到同样的属性值。如果委托的初始化函数不需要同步,可以向lazy函数传入一个(LazyThreadSafetyMode.PUBLICATION)参数。想法如果你确信初始化函数只可能在一个线程中执行,那么可以使用(LazyThreadSafetyMode.NONE)模式,这种模式不会保持线程同步,因此不会带来这方面的损失。

2.可观察属性

所谓可观察属性就是当属性变化可以拦截其变化。
Delegates.observable() 需要俩个参数:一个初始值和一个修改者的 handler。每次我们分配属性时都会调用handler (在分配前执行)。它有三个参数:一个分配的属性,旧值,新值:

import kotlin.properties.Delegates

//  标准委托:可观察属性

//  Delegates.observable
//  接受两个参数:1. 初始化值   2.属性值变化时响应器(Handler)
//  响应器: 1. prop   2. old    3. new
class User
{
    var name:String by Delegates.observable("Mike")
    {
        prop,old,new ->
        println("旧值:${old}  新值:${new}")
    }
}
fun main(args: Array<String>)
{
    val user = User()
    user.name = "Bill"
    user.name = "John"
}

输出:
这里写图片描述

3.阻止属性

如果你希望能够拦截属性的赋值操作,并且还能够“否决”赋值操作,那么不要使用observable函数,而应该使用vetoable函数。传递给vetoable函数的时间响应器会返回一个布尔类型的值,如果返回true,表示允许给属性复制,如果false,就会否决属性的赋值(仍然保留原来的值)

//  标准委托:阻止属性的赋值操作
//  vetoable函数
class User1
{
    var name:String by Delegates.vetoable("Mike") {
        prop,old,new->
        println("旧值:${old}  新值:${new}")
        var result = true
        // name属性值不能是Mary
        if(new.equals("Mary"))
        {
            result = false
            println("name属性值不能是Mary")
        }
        result
    }
}

fun main(args: Array<String>)
{
    val user = User1()
    user.name = "Bill"
    println(user.name)
    user.name = "Mary"
    println(user.name)
}

输出:

这里写图片描述

4. Map委托

Delegates.mapVal() 拥有一个 map 实例并返回一个可以从 map 中读其中属性的代理。在应用中有很多这样的例子,比如解析 JSON 或者做其它的一些 “动态”的事情:

class User2(var map: Map<String, Any>) {
    val name: String by map  //将map用作name属性的委托
    val age: Int by map  //将map用作age属性的委托
}

fun main(args: Array<String>) {
    var map = mapOf("name" to "lulu","age" to 22)
    val user = User2(map)  //将map中的key-value直接映射到User类的属性上
    println(user.age)
    println(user.name)
}

输出:
这里写图片描述

5. MutableMap委托

如果要让上一小节的User2类的那么和age属性映射到可读写的委托,需要将这两个属性委托给 MutableMap

class User3(var map: MutableMap<String, Any>) {
    var name: String by map  //将map用作name属性的委托
    var age: Int by map  //将map用作age属性的委托
}

fun main(args: Array<String>) {
    var map = mutableMapOf("name" to "lulu","age" to 22)
    val user = User3(map)  //将map中的key-value直接映射到User类的属性上
    println(user.age)
    println(user.name)
    user.age = 88
    user.name = "ddd"
    println(user.age)
    println(user.name)
}

输出:
这里写图片描述

我们可以看到。如果将属性委托给MutableMap,那么变化是双向的。无论是修改MutableMap中的值,还是User类的属性值,变化都是同步的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值