Kotlin-20.代理/委托属性(delegated properties)
2017-06-26 22:49
351 查看
官方文档: http://kotlinlang.org/docs/reference/delegated-properties.html
简书:http://www.jianshu.com/p/2464a5106f12
CSDN博客: http://blog.csdn.net/qq_32115439/article/details/73751666
GitHub博客:http://lioil.win/2017/06/26/Kotlin-delegated-properties.html
Coding博客:http://c.lioil.win/2017/06/26/Kotlin-delegated-properties.html
1.委托属性
一些常见的属性类型: 懒加载属性(lazy properties): 只在首次访问时计算属性值; 可观察属性(observable properties): 监听器可以收到此属性变化的通知; 一个映射(map)存储多个属性,而不是一个属性对应一个字段! 为涵盖这些情况,Kotlin支持委托属性(delegated properties): import kotlin.reflect.KProperty //导入库 class Example { //by Delegate()表示: 属性p的get()和set()会被委托给Delegate的getValue()和setValue() var p: String by Delegate() } class Delegate() { // 取代Example的属性p的get() operator fun getValue(t: Any?, prop: KProperty<*>): String { // 第一个参数t: 被代理的对象(本例中Example对象) // 第二参数prop: 被代理的对象的属性(本例中Example对象的属性p) return "$t, ${prop.name}" } // 取代Example的属性p的set() operator fun setValue(t: Any?, prop: KProperty<*>, value: String) { // 第三个参数: 被代理的对象的属性值(本例中Example对象的属性p的值) println("$t, ${prop.name}, $value") } } fun main(args: Array<String>) { val e = Example() println(e.p) //调用get方法 输出 Example@6267c3bb, p e.p = "MyVal" //调用set方法 输出 Example@6267c3bb, p, MyVal }
2.懒加载属性(lazy properties)
by lazy({ })是接受lambda并返回一个Lazy<T>对象的函数, 返回对象可作为委托,实现了懒加载属性(lazy properties): val a: String by lazy { //第一次调用会执行该lamda表达式,并记录结果 //后续调用只返回已记录的结果 println("******") "Hello" "返回结果" //lamda表达式最后一行作为lazy函数返回值,记录结果 } fun main(args: Array<String>) { println(a) println(a) } 输出: ****** "返回结果" "返回结果" 默认情况下,lazy{}是同步锁住(synchronized): 只能有一个线程执行,其它线程必须等待! 如果需要多个线程同时执行lazy{},那么传递参数LazyThreadSafetyMode.PUBLICATION给lazy()函数 如果确定lazy{}总是单个线程,那么传递参数LazyThreadSafetyMode.NONE,不保证线程安全! val a: String by lazy(LazyThreadSafetyMode.NONE){ ... } val a: String by lazy(La 4000 zyThreadSafetyMode.PUBLICATION){ ... } 自kotlin 1.1起,可将局部变量声明为委托属性,例如lazy懒加载属性: fun example(computeFoo: () -> Foo) { val memoizedFoo by lazy(computeFoo) if (someCondition && memoizedFoo.isValid()) { memoizedFoo.doSomething() } }
3.可观察属性(observable properties)
Delegates.observable()有两个参数: 初始值、属性变化时的回调(handler) import kotlin.properties.Delegates //导入库 class User { //如果要拦截(veto否决)赋值,就用vetoable()取代observable()! var name: String by Delegates.observable("initName") { //回调有三个参数:被观察的属性、属性旧值和属性新值 prop, old, new -> println("$old ---> $new") } } fun main(args: Array<String>) { val user = User() user.name = "name111" user.name = "name222" } 输出: initName ---> name111 name111 ---> name222
4.一个映射(map)存储多个属性(Storing Properties in a Map)
一个映射(map)存储多个属性,这时可用映射实例对象作为委托,实现委托属性! class User(val map: Map<String, Any?>) { val name: String by map val age: Int by map } //1.使用map代理多个属性 val user = User(mapOf( "name" to "lioil", "age" to 24 )) //2.从map中读取多个属性值 println(user.name) // 输出 lioil println(user.age) // 输出 24 //把只读Map改为可变MutableMap,也适用于var属性 class MutableUser(val map: MutableMap<String, Any?>) { var name: String by map var age: Int by map }
简书:http://www.jianshu.com/p/2464a5106f12
CSDN博客: http://blog.csdn.net/qq_32115439/article/details/73751666
GitHub博客:http://lioil.win/2017/06/26/Kotlin-delegated-properties.html
Coding博客:http://c.lioil.win/2017/06/26/Kotlin-delegated-properties.html
相关文章推荐
- Kotlin笔记(七)——委托属性(Delegated Properties)
- Kotlin学习(十八): 委托模式(Delegate)和委托属性(Delegate Properties)
- Kotlin-代理属性(by)
- Kotlin的属性委托:无上下文情况下Android的赋值(KAD 15)
- Kotlin的委托属性和区间
- Kotlin的属性代理
- iOS--页面间的代理传值(属性、代理(委托)、代码块、单例、通知)
- Kotlin的属性委托:无上下文情况下Android的赋值(KAD 15)
- Kotlin的属性委托:无上下文情况下Android的赋值(KAD 15)
- Kotlin开发笔记之委托属性与区间(译)
- Kotlin-09.类属性和字段(Properties/Fields)
- Kotlin代理属性--官方文档翻译
- Kotlin-委托属性
- Kotlin随笔 委托属性之延迟加载
- Kotlin代理属性--官方文档翻译
- kotlin委托属性+SharedPreference实例
- 深入Kotlin - 专项 - 委托属性-1
- Kotlin(2.13)代理属性
- Kotlin学习之-5.13 代理属性
- kotlin面向对象之接口、代理与委托、单例模式