延迟初始化 lateinit , lazy
lateinit, lazy 是 Kotlin 中两种实现延迟初始化的方式.
- lateinit 只能用于 var 标示的变量,by lazy 只能用于 val 标示的变量。
- by lazy 只在第一次调用时进行初始化。
class User {
private lateinit var name: String
private val password: String by lazy {
println("lazy init")
"admin"
}
fun setName(name: String) {
this.name = name
}
fun show() {
println("name = $name")
println("--------------------")
println("第一次访问 password = $password")
println("第二次访问 password = $password")
}
}
fun main() {
val user = User()
user.setName("tomcat")
user.show()
}
输出结果:
name = tomcat
--------------------
lazy init
第一次访问 password = admin
第二次访问 password = admin
委托 by
/**
* 定义 Base 接口
*
*/
interface Base {
fun say()
}
/**
* 定义 Base 接口的实现类,并实现 say() 方法
*/
class BaseImpl : Base {
override fun say() {
println("BaseImpl say()")
}
}
/**
* 定义 BaseProxy 类,并实现了 Base 接口,
* 关键字 by 将接口 Base 中所有的方法都委托给 base 对象,这样 BaseProxy 类就不需要去实现接口 Base 中的方法了,
* 简化了实现接口时要实现其中的方法。
*/
class BaseProxy(base: Base) : Base by base
fun main() {
val baseImpl = BaseImpl()
// 调用的是 BaseImpl 中的 say() 方法
BaseProxy(baseImpl).say()
}
输出结果:
BaseImpl say()
扩展函数
扩展函数可以给类额外添加成员函数,通过 "类名.方法名" 方式实现。
/**
* 定义扩展函数,给 File 添加 readText() 方法
*/
fun File.readText(charset: Charset): String = readBytes().toString(charset)
// 调用
fun main() {
val file = File("/Users/xing/Desktop/Android.md")
print(file.readText(Charset.forName("utf-8")))
}
Lambda 闭包
Lambda 表达式本质是 匿名函数,其底层实现是通过 匿名函数来实现的。
特点:
-
Lambda 表达式总是被大括号括着;
-
其参数(如果存在) , 则在 -> 之前声明;
-
函数体(如果存在),则在写在 -> 后面;
-
如果 Lambda 是函数的最后一个参数,可以将大括号放到函数小括号外面。
-
如果函数只有一个参数且这个参数是 Lambda,则可以省略小括号。