Kotlin语法(七)

本文介绍了Kotlin中的属性代理概念及其实现方式,包括通过delegate、lazy和observable属性的使用方法,并展示了如何利用map实现属性代理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

属性代理(delegated properties)

在Kotlin中,我们可以不直接给属性赋值而是通过代理的方式。主要的方法有以下三种:
(1)通过delegate的方式进行赋值
(2)lazy properties,只有在第一次调用它的get方法时才会进行赋值
(3)observable properties, 对属性值得改变进行监听

  • 通过代理的方式
    语法格式为val/var : by , 这个property的赋值将会通过后边的expression进行赋值,expression有一个或两个方法getValue 和setValue(var时会有此方法),与property的get, set方法相对应。调用property的get方法时就会委托给expression的getValue方法,set方法也会这样。代码如下:
class Example {
    var p: String by Delegate ()
}

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

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

val e = Example()
println(e.p)

//打印结果如下=====
//Example@33a17727, thank you for delegating ‘p’ to me!

e.p = "NEW"
//打印结果如下
//NEW has been assigned to ‘p’ in Example@33a17727.
  • lazy property
    lazy() 是一个带有lambda参数的方法,如果是第一次初始化的时候会调用lazy()方法,之后会将lazy()方法的结果储存起来,以后再次使用这个property的时候将直接使用储存起来的值。示例代码如下:
val lazyValue: String by lazy{
    println("invoke lazy fun")
    "hello"
}

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


//打印结果为:
computed!
hello
hello

默认情况下lazy方法是synchronized的。如果不需要使用线程同步我们可以给lazy传一个参数LazyThreadSafetyMode.PUBLICATION,如果我们非常确定将只会在一个线程中使用则我们可以传参LazyThreadSafetyMode.NONE

  • observable property
    我们使用的是Delegates.observable(…)方法, 它有两个参数,第一个参数时初始化值,第二个参数为lambda,这个lambda有三个参数:KProperty, oldValue, newValue。如果这个属性的值发生变化时,将会调用lambda。示例代码如下:
import kotlin.properties.Delegates

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

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

//打印结果为:
<no name> -> first
first -> second
  • map property
    在应用中我们经常用map来存储数据,kotlin中我们可以通过map给所有的property赋值,简直简单到爆啊。示例代码如下:
class User(val map: Map<String, Any?>){
    val name: String by map
    val age: Int by map
}

val user = User(mapOf("name" to "zhangsan", "age" to 21))

println(user.name) // Prints "John Doe"
println(user.age)  // Prints 25

如果我们的属性是var的,那我们需要使用MutableMap

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值