一、let函数
上下⽂对象作为 lambda 表达式的参数( it )来访问。返回值是 lambda 表达式的结果。一般作用于非空的对象。let 可⽤于在调⽤链的结果上调⽤⼀个或多个函数。
Boy对象:
class Boy(var name: String, var age: Int, var address: String) {
fun study() {
println("${name} study")
}
}
调用示例:
val boy = Boy("小明", 15, "广州市")
boy.let {
println("My name is ${it.name} ,I'm ${it.age} years old and I come form ${it.address} ")
it.study()
}
let 经常⽤于仅使⽤⾮空值执⾏代码块。如需对⾮空对象执⾏操作,可对其使⽤安全调⽤操作符 ?. 并调⽤ let 在 lambda 表达式中执⾏操作。
二、with函数
⼀个⾮扩展函数:上下⽂对象作为参数传递,但是在 lambda 表达式内部,它可以作为接收者( this )使⽤。返回值是 lambda 表达式结果。 我们建议使⽤ with 来调⽤上下⽂对象上的函数,⽽不使⽤ lambda 表达式结果。在代码中,with 可以理解为“对于 这个对象,执⾏以下操作。
调用示例一:
val boy = Boy("小明", 15, "广州市")
with(boy){
println("My name is $name ,I'm $age years old and I come form $address ")
}
调用示例二:
val numbers = mutableListOf("one", "two", "three")
with(numbers) {
println("'with' is called with argument $this")
println("It contains $size elements")
}
三、run函数
run函数有两种用法,一种是作用于上下⽂对象 作为接收者( this )来访问,返回值 是 lambda 表达式结果,run 和 with 做同样的事情,但是调⽤⽅式和 let ⼀样⸺作为上下⽂对象的扩展函数。一种非扩展函数,⾮扩展 run 可以使你在需要表达式的地⽅执⾏⼀ 个由多个语句组成的块。
- 作用于上下文对象
Service对象
class Service(var url:String,var port:Int) {
fun getServiceAddress():String{
return url.plus(":").plus(port)
}
}
run函数代码示例:
val service = Service("https://www.baidu.com", 8080)
var path = service.run {
getServiceAddress()
}
println(path)
let函数代码示例:
var path = service.let {
it.getServiceAddress()
}
- 非扩展函数
val baiduPath = run {
val url = "https://www.baidu.com"
val port = 8080
url.plus(":").plus(port)
}
四、apply函数
上下⽂对象 作为接收者( this )来访问,返回值 是上下⽂对象本⾝。对于不返回值且主要在接收者( this )对象的成员上运⾏的代码块使⽤ apply 。apply 的常⻅情况是对象配置。这 样的调⽤可以理解为“将以下赋值操作应⽤于对象”。
apply函数示例
Student对象
class Student {
var grade: Int = 0
var name: String? = null
var address: String? = null
}
val student = Student().apply {
address = "广州"
grade = 5
name = "小红"
}
println("我的名字是${student.name},上${student.grade}年级,我来自${student.address}")
五、also函数
上下⽂对象作为 lambda 表达式的参数( it )来访问。返回值是上下⽂对象本⾝。 also 对于执⾏⼀些将上下⽂对象作为参数的操作很有⽤。对于需要引⽤对象⽽不是其属性与函数的操作,或者不想 屏蔽来⾃外部作⽤域的 this 引⽤时,请使⽤ also 。 当你在代码中看到 also 时,可以将其理解为“并且⽤该对象执⾏以下操作”。
val student = Student().apply {
address = "广州"
grade = 5
name = "小红"
}
student.also {
println("${it.name} 是一个好学生哦")
}
六、函数比较
函数 | 对象引用 | 返回值 | 是否扩展函数 |
---|---|---|---|
let | it | Lambda 表达式结果 | 是 |
run | this | Lambda 表达式结果 | 是 |
run | - | Lambda 表达式结果 | 不是:调⽤⽆需上下⽂对象 |
with | this | Lambda 表达式结果 | 不是:把上下⽂对象当做参数 |
apply | this | 上下文对象 | 是 |
also | it | 上下文对象 | 是 |
以下是根据预期⽬的选择作⽤域函数的简短指南:
- 对⼀个⾮空(non-null)对象执⾏ lambda 表达式:let
- 将表达式作为变量引⼊为局部作⽤域中:let
- 对象配置:apply
- 对象配置并且计算结果:run
- 在需要表达式的地⽅运⾏语句:⾮扩展的 run
- 附加效果:also
- ⼀个对象的⼀组函数调⽤:with