懒加载: the value gets computed only upon first access
1 2 3 4 5 6 7 8 9 10
//通过使用工厂方法lazy()获得Lazy<T>实例 funmain(args:Array<String>){ //lazy没有提供setter,所以使用lazy代理的属性必须为val val str:String by lazy{ //Lazy<T>懒加载,只会在第一次时执行 println("lazy") "hello" } println(str) println(str) }
observable properties: listeners get notified about changes to this property
1 2 3 4 5 6 7 8 9 10 11 12 13
funmain(args:Array<String>){ var p=Person() println(p.name) p.name="Jim" println(p.name) }
classPerson{ var name by Delegates.observable("no-name"){ //set时被调用 prop,old,new-> println("$prop($old->$new)") } }
storing properties in a map, not in separate field each
1 2 3 4 5 6 7 8 9 10 11
funmain(args:Array<String>){ var p=Person(mutableMapOf("name" to "Tim","age" to 10)) println(p.name) println(p.age)
}
classPerson(map:MutableMap<String,Any?>){ var name:String by map var age:Intby map }
工作原理
1 2 3 4 5 6 7 8 9 10 11
classC{ var prop: Type by MyDelegate() } // this code is generated by the compiler // when the 'provideDelegate' function is available: classC{ // calling "provideDelegate" to create the additional "delegate" property privateval prop$delegate = MyDelegate().provideDelegate(this, this::prop) val prop: Type get() = prop$delegate.getValue(this, this::prop) }
kotlin 1.1之后,代理属性可以用于local-properties
方法代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
funmain(args:Array<String>){ var b=B(AImpl()) b.echo() }
interfaceA{ funecho() }
classAImpl:A{ overridefunecho(){ println("a implemention of A") } } classB(impl:AImpl):A by impl //impl提供B的接口方法