扩展函数。
例如:
fun Context.toast(msg: String, length: Int = Toast.LENGTH_SHORT){
Toast.makeText(this, msg, length).show()
}
使用
val activity: Context? = getActivity()
activity?.toast("Hello world!")
activity?.toast("Hello world!", Toast.LENGTH_LONG)
委托
Kotlin 中,使用by关键字表示委托:
interface Animal {
fun bark()
}
// 定义 Cat 类,实现 Animal 接口
class Cat : Animal {
override fun bark() {
println("喵喵")
}
}
// 将 Zoo 委托给它的参数 animal
class Zoo(animal: Animal) : Animal by animal
fun main(args: Array<String>) {
val cat = Cat()
Zoo(cat).bark()
}
// 输出结果:喵喵
属性委托标准使用懒加载
// 通过 by 关键字,将 lazyValue 属性委托给 lazy {} 里面的实现
val lazyValue: String by lazy {
val result = compute()
println("computed!")
result
}
// 模拟计算返回的变量
fun compute():String{
return "Hello"
}
fun main(args: Array<String>) {
println(lazyValue)
println("=======")
println(lazyValue)
}
输出
computed!
Hello
=======
Hello
by lazy 这种委托的方式,可以让我们轻松实现懒加载
lazy 委托的三种线程模式,他们分别是:
LazyThre
- adSafetyMode.SYNCHRONIZED
- LazyThreadSafetyMode.NONE
- LazyThreadSafetyMode.PUBLICATION
1,LazyThreadSafetyMode.SYNCHRONIZED 通过加锁实现多线程同步,这也是默认的模式。
2,LazyThreadSafetyMode.NONE 则没有任何线程安全代码,线程不安全。
3,它的初始化方法是可能会被多个线程执行多次的,但最后这个变量的取值是仅以第一次算出的值为准的。即,哪个线程最先算出这个值,就以这个值为准。
最后聊一个很好用的基于委托的小工具
class User {
// 为 name 这个变量添加观察者,每次 name 改变的时候,都会执行括号内的代码
var name: String by Delegates.observable("<no name>") {
prop, old, new ->
println("name 改变了:$old -> $new")
}
}
fun main(args: Array<String>) {
val user = User()
user.name = "first: Tom"
user.name = "second: Jack"
}
输出:
name 改变了:<no name> -> first: Tom
name 改变了:first: Tom -> second: Jack