注:前面的主要是概念解释,源于《Kotlin实战》一书,apply的使用问题在最下面,如果对于with和apply的概念很熟悉可以直接看下面内容。 kotlin标准库中apply函数和with函数是带接受者的lambda。这两个函数可以使我们对同一对象执行多次操作,而不需要把对象的名称写出来。 #with 代码清单1:使用whith构建字母表
fun alphabet(): String{
val result = StringBuilder()
for (letter in 'A'..'Z') {
result.append(letter)
}
result.append("\nNow I know the alphabet!")
return result.toString()
}
下面是用with进行代码优化 代码清单2:
fun alphabet() = with(StringBuilder()) {
for (letter in 'A'..'Z') {
append(letter)
}
append("\nNow I know the alphabet!")
toString()
}
由此可以发现 with可以消除清单1中对变量名字的显示引用,同时返回lambda的最后一个表达式的值。但是有时候我们想返回的是接受者对象,而不是结果时,这时候就需要使用apply了。 #apply apply的作用和with几乎一样,唯一区别是apply会始终返回作为实参传递给它的对象(换句话说,就是接受者对象)。下面是用apply进行重构刚才的alphabet函数。 代码清单3:
fun alphabet() = StringBuilder().apply {
for (letter in 'A'..'Z') {
append(letter)
}
append("\nNow I know the alphabet!")
}.toString()
在Android上使用的时候可以用这种方式对一些实例进行创建并初始化 代码清单4:
fun createViewWithCustomAttributes(context: Context) =
TextView(context).apply {
text = "Sample Text"
textSize = 20.0f
}
至此,概念全部结束 *** 请看一下两段代码的运行结果: 代码清单5
fun main(args: Array<String>) {
//sampleStart
class User(var age: Int, var name: String)
var u = User(11,"22")
var u2 = User(22,"33")
fun applyTest() = u.apply {
u.age = u2.age
}
//sampleEnd
}
@Test
fun test(){
println("----age:"+applyTest().age)
println("----age:"+u.age)
println("----age:"+u.age)
}
>>>----age:22
>>>----age:22
>>>----age:22
println("")
代码清单6:
class User(var age: Int, var name: String)
var u = User(11,"22")
var u2 = User(22,"33")
fun applyTest() = u.apply {
u = u2
}
@Test
fun test(){
println("----age:"+applyTest().age)
println("----age:"+u.age)
println("----age:"+u.age)
}
>>>----age:11
>>>----age:22
>>>----age:22
由此可以知道,如果直接在T.apply里面改变T的话,第一次运行是没有结果的(基本类型也是),但是如果这个变量是对象的话,并且改变的是对象里面的属性的话,第一次运行是有效果的。如果想让第一次改变对象有效果,需要在apply的函数体内,显示调用 return 返回这个对象,例如以下方式:
代码清单7:
class User(var age: Int, var name: String)
var u = User(11,"22")
var u2 = User(22,"33")
fun applyTest() = u.apply {
u = u2
return u
}
@Test
fun test(){
println("----age:"+applyTest().age)
println("----age:"+u.age)
println("----age:"+u.age)
}
>>>----age:22
>>>----age:22
>>>----age:22