1.符号
- ?符号可以为可空的接收者类型定义扩展。这样的扩展可以在对象变量上调⽤,即使其值为 null,并且可以在函数体内检测 this == null ,这能让你在没有检测 null 的时候调⽤ Kotlin 中的toString():检测发⽣在扩展函数的内部。
fun Any?.toString(): String {
if (this == null) return "null"
// 空检测之后,“this”会⾃动转换为⾮空类型,所以下⾯的 toString()
// 解析为 Any 类的成员函数
return toString()
}
2 关键字
- by 实现委托
- vararg:可变参数
- apply函数可看作一个配置函数,你可以传入一个接收者, 然后调用一系列函数来配置它以便使用。如果提供 lambda 给 apply 函数执行,它会返回配置好的接收者。
val menuFile = File("menu-file.txt")
menuFile.setReadable(true)
menuFile.setWritable(true)
menuFile.setExecutable(false)
//用上 apply 函数,实现同样的配置时,代码简洁多了:
val menuFile = File("menu-file.txt").apply {
setReadable(true)
setWritable(true)
setExecutable(false)
}
- let函数 能使某个变量作用于其 lambda 表 达式里,让 it 关键字能引用它。返回值为函数块的最后一行或指定return表达式。let 函数的实际上是一个作用域函数,当你需要去定义一个变量在一个特定的作用域范围内,let函数的是一个不错的选择;let函数另一个作用就是可以避免写一些判断null的操作。
val firstItemSquared = listOf(1,2,3).first().let {
it * it
}
//如果不用 let 函数,那么你需要把第一个数赋给一个变量,然后操作变量:
val firstElement = listOf(1,2,3).first()
val firstItemSquared = firstElement * firstElement
object.let{
it.todo()//在函数体内使用it替代object对象去访问其公有的属性和方法
...
}
//另一种用途 判断object为null的操作
object?.let{//表示object不为null的条件下,才会去执行let函数体
it.todo()
}
*also函数 和 let 函数功能相似。和 let 一样,also 也是把接收者作为值参传给 lambda。但有一点不同:also 返回接收者对象,而 let 返回 lambda 结果。
var fileContents: List<String>
File("file.txt")
.also {
print(it.name)
}.also {
fileContents = it.readLines()
} }
- run 函数实际上可以说是let和with两个函数的结合体,run函数只接收一个lambda函数为参数,以闭包形式返回,返回值为最后一行的值或者指定的return的表达式。准确来说它弥补了let函数在函数体内必须使用it参数替代对象,在run函数中可以像with函数一样可以省略,直接访问实例的公有属性和方法,另一方面它弥补了with函数传入对象判空问题,在run函数中可以像let函数一样做判空处理
val user = User("Kotlin", 1, "1111111")
val result = user.run {
println("my name is $name, I am $age years old,
my phone number is $phoneNum")
1000
}
println("result: $result")
- takeIf函数需要判断 lambda 中提供的条件表达式(叫 predicate),给出 true 或 false 结果。如果判断结果是 true,从 takeIf 函数返回接收者对象;如果是 false,则返回 null
- until 循环
for (i in 1 until 5) {
print(i) // 1234
}
网友评论