标准函数with、run、apply
with函数接收两个参数:任意类型的对象,Lambda表达式。with函数会在Lambda表达式中提供第一个参数对象的上下文,并使用Lambda表达式中的最后一行代码作为返回值。示例代码如下:
val result=with(obj){
//这里是obj的上下文
"value"//with函数的返回值
}
它可以在连续调用一个对象时的多个方法时让代码变得更加精简。直接举例:
val list= listOf("apple","banana","watermelon","pear")
val result= with(StringBuilder()){
append("Start eating fruits.\n")
for (fruit in list){
append(fruit).append("\n")
}
append("Ate all fruits")
toString()
}
println(result)
with函数的第一个参数传入StringBuilder()对象,Lambda的上下文 就会是这个对象,然后在表达式里直接调用append()和toString()方法。
run函数要在某个对象的基础上调用:其次run函数只接收一个Lambda参数,其他与with用法一样,在Lambda表达式中调用对象的上下文。示例代码:
val result=obj.run{
//obj的上下文
"value"//run函数返回的对象
}
用run函数来修改一下这段吃水果的代码,只做了非常小的一点变化:
val result= StringBuilder().run
apply函数也是要在某个对象上调用,只接收一个Lambda函数,也会在Lambda表达式中提供调用对象的上下文,但apply函数无法指定返回值,而是会返回调用对象本身。示例函数如下:
val return=obj.apply{
//这里是obj的上下文
}
//result==obj
再次修改吃水果的代码:
val result= StringBuilder().apply{
append("Start eating fruits.\n")
for (fruit in list){
append(fruit).append("\n")
}
append("Ate all fruits")
}
println(result.toString())
由于apply函数无法指定返回值,因此这里result实际上是StringBuilder对象,最后打印时需要调用它的toString()方法。
定义静态方法
静态方法又叫做类方法,指的是那种不需要创建实例就能调用的方法。
在java中定义静态方法很简单,只需要在方法上声明一个static关键词就行了。但Kotlin想定义一个静态方法反而不简单。因为Kotlin提供了比静态方法更好用的语法特性——单例类。像工具类这种功能,就非常推荐用单例类的方法来实现。
不过使用单例类会让整个类中的所有方法全部变成类似与静态方法的调用方式,如果想让类中的某一个方法变成静态方法,这时候就可以使用companion object了:
class Util{
fun doAcion1{
println("do action1")
}
companion object{
fun doAction2{
println("do action2")
}
}
}
这里我们的Util是一个普通类,在类中定义了一个doAction1()方法,又在companion object中定义doAction2()方法。现在这两个方法就不一样了,前者必须要先创建这个类的实例才能调用,后者可以直接使用Util.doAction2()的方式调用。
不过这其实也并不是静态方法,这个关键词会在这个类的内部创建一个伴生类,而doAction2()就是定义在这个伴生类的实例方法。只是kotlin保证Util只会有一个伴生类对象,因此调用Util.doAction2()就是调用伴生对象的doAction2()方法。
Kotlin还是提供了两种实现静态方法的方式:注解和顶层方法。
前面的单例类和companion object只是语法的形式模仿了静态方法的调用方式。而当我们给单例类和companion object的方法上加上@JvmStatic注解,那么就会成为真正的静态方法
companion object{
@JvmStatic
fun doAction2{
println("do action2")
}
}
再看顶层方法,顶层方法指的是那些没有定义在任何类中的方法。Kotlin会将所有的顶层方法编译成静态方法,因此你只要定义了顶层方法,那它就一定是静态方法。
想要定义一个顶层方法,先创建一个Kotlin文件,创建类型选择File。我们在这个文件中定义的任何方法都会是顶层方法,我们在这定义一个doSomething()方法:
fun doSomething(){
println("do something")
}
Kotlin会将所以顶层方法全部编译成静态方法。那么我们要怎么调用它呢?
如果在Kotlin代码中调用的话,直接键入doSomething()即可。但是在Java中调用会发现找不到这个方法,因为Java中不存在什么顶层方法,在Java中调用时使用Helper.doSomething()的写法来调用就可以了。