apply():可以看做是一个配置函数,传入一个接收者,然后调用一系列方法配置它以便使用,最后返回配置好的接收者
fun main() {
val file1 = File("D://file.txt")
file1.setExecutable(true)
file1.setReadable(true)
file1.setWritable(true)
val apply:File = file1.apply {
setExecutable(true)
setReadable(true)
setWritable(true)
}
}
let():let函数使某个变量作用于其Lambda表达式里,让it关键字能引用它,与apply比较,let会把接收者传给lambda,而apply什么都不传。匿名函数执行完,apply会返回当前接收者,let会返回lambda的最后一行
val result = listOf(1, 2, 3).first().let {
it * it
}
fun formatGreeting(guestName: String?): String {
return guestName?.let {
"welcome $it"
} ?: "who are you"
}
run():run不返回接收者,返回的是lambda的结果
val file1 = File("D://file.txt")
val run = file1.run {
readText().contains("abc")
}
var str = "abcdefghijklmn"
str.run {
length>10
}
run函数支持链式调用
var str = "abcdefghijklmn"
str.run(::isLong).run(::showMessage).run(::print)
fun isLong(name: String) = name.length > 10
fun showMessage(isLong: Boolean): String {
return if (isLong) {
"Too Long"
} else {
return "not too long"
}
}
with():with是run函数的变体,with的调用方式不同,调用with时需要 值参作为其第一个参数传入
with(str){
length>10
}
also():also函数和let函数功能相似,和let一样,also把接收者作为值参传给lambda,但是有一点不同:also返回接收者对象,而let返回lambda结果
利用这个差异,also适合针对同一原始对象,利用副作用做事,also返回接收者对象,就可以基于原始接收者对象执行额外的链式调用
var fileContents:List<String>
File("D://file.txt").also {
print(it.name)
}.also {
fileContents = it.readLines()
}
println(fileContents)
takeIf():takeIf需要判断lambda中提供的条件表达式,给出true、false结果,如果判断为true,从takeIf函数返回接收者对象,如果是false,则返回null。如果需要判断某个条件是否满足,再决定是否可以赋值变量或者执行某项任务,takeIf就非常有用
val readResult:String = File("D://file.txt").takeIf {
it.exists() && it.canRead()
}?.readText() ?: "null"
print(readResult)
takeUnless():是takeIf的辅助函数,只有判断你给定的条件结果是false时,takeUnless才会返回原始接收者对象
File("D://file.txt").takeUnless {
it.isHidden
}?.readText() ?: "null"