1. 几个标准函数
Kotlin中标准函数指的是Standard.kt文件中定义的函数,任何Kotlin代码都可以任意的调用所有的标准函数。上一篇文章中我们学习了let函数配合?.操作符来避免空指针引发的问题,这篇文章中我们会继续学习几个标准函数。
1.1 with
with函数接收两个参数:第一个参数可以是一个任意类型的对象,第二个参数是一个Lambda表达式。with函数会在Lambda表达式中提供第一个参数对象的上下文,并使用Lambda表达式中的最后一行代码作为返回值返回。
我们先来看一段代码:
fun main(){
val list = listOf<String>("a","b","c","d","e")
val builder = StringBuilder()
builder.append("start ")
for (letter in list){
builder.append(letter+" ")
}
builder.append("end ")
val result = builder.toString()
println("result is $result")
}
//result is start a b c d e end
上段代码中,我们调用了很多次builder对象的方法,导致我们写了很多次builder,我们可不可以光调用它的方法,而不用写很多次builder呢,with函数就可以让我们的代码简单很多。
fun main(){
val list = listOf<String>("a","b","c","d","e")
val result = with(StringBuilder()){
append("start ")
for (letter in list){
append(letter+" ")
}
append("end ")
toString()
}
println("result is $result")
}
//result is start a b c d e end
with函数接收两个参数:第一个参数可以是一个StringBuilder()对象,第二个参数是一个Lambda表达式。此处因为Lambda表达式为最后一个参数,因此可以写在方法括号外边,接下来在Lambda表达式中的上下文就是StringBuilder()对象,于是就可以调用StringBuilder()对象的方法,最后一行代码toString()作为返回值返回。
1.2 run
run函数和with函数很类似,但有两点不同:
- 通常不会直接调用,而是在某个对象的基础上调用
- 只接收一个Lambda表达式作为参数
其它和with函数是一样的,只是在Lambda表达式中的上下文变为调用对象,同样使用Lambda表达式中的最后一行代码作为返回值返回。
上段代码的run函数版本就是这个样子的:
fun main(){
val list = listOf<String>("a","b","c","d","e")
val result = StringBuilder().run{
append("start ")
for (letter in list){
append(letter+" ")
}
append("end ")
toString()
}
println("result is $result")
}
//result is start a b c d e end
总体来说变化很小,只是将with函数的参数StringBuilder对象变为了调用StringBuilder对象的run方法而已,其它并没有区别。
1.3 apply
apply函数和run函数也很相似,同样需要在某个对象的基础上调用,并且只接收一个Lambda表达式作为参数,也会在Lambda表达式中提供调用者的上下文,不同的是apply函数无法指定返回值,而是会返回调用者本身。
上段代码的apply函数版本就是这个样子的:
fun main(){
val list = listOf<String>("a","b","c","d","e")
val result = StringBuilder().apply{
append("start ")
for (letter in list){
append(letter+" ")
}
append("end ")
}
println("result is ${result.toString()}")
}
//result is start a b c d e end
这里我们只是无法返回StringBuilder()对象的toString()方法了,而apply函数返回的是StringBuilder()整个对象,因此,我们在打印时需要调用StringBuilder()对象的toString()方法。
2. 静态方法
2.1 单例类和伴生类实现类似静态方式调用
静态方法指的就是不需要实例就可以调用的方法,在Java中,只需要在方法前加上static关键字就可以了,但是Kotlin却极度的弱化了静态方法的概念,但是却提供了类似的方法,共开发者实现业务逻辑。
还记得在 Kotlin-类与对象(第一行代码Kotlin学习笔记2)中的单例类吗,我们可以这么写:
object Util {
fun doAction(){
println("------doAction-----")
}
}
这样,我们就可以使用Util.doAction()的方式来调用方法了,但此处的doAction()并不是静态方法。但是如果我们并不需要类中的全部方法都可以这么调用,只是部分方法需要以累名.方法名的方式调用怎么办呢?这时我们可以使用companion object
class Util {
fun doAction1() {
println("------doAction1-----")
}
companion object {
fun doAction2() {
println("------doAction2-----")
}
}
}
这里的doAction2()就可以使用Util.doAction2()的方式来调用,当这同样也不是一个静态方法,companion object关键字实际上会在Util类内部创建一个伴生类,而doAction2()就是定义在伴生类中的实例方法,并且Kotlin会保证一个类始终只能存在一个伴生类对象。
2.2 静态方法
上述方式只是类似于静态方法的写法,但并不是真正的静态方法,如果在Java代码中,我们就无法以静态方法的调用方式去调用,只能以Util.Companion.doAction2();或Util.INSTANCE.doAction();的方式调用,那我们想真正的定义静态方法怎么办呢?Kotlin提供了两种方式:
- 注解@JvmStatic(注:只能添加在单列类或companion object内的方法中)
- 顶层方法
注解
class Util {
companion object {
@JvmStatic
fun doAction2() {
println("------doAction2-----")
}
}
}
编译器会将添加过注解@JvmStatic的方法编译为真正的静态方法,但是需要注意的是这个注解只能添加在单列类或companion object内的方法中,否则会提示语法错误。
顶层方法
Kotlin中顶层方法是指没有定义在任何类中的方法,就是我们直接定义在.kt文件中的方法,Kotlin编译器会将所有的顶层方法编译为静态方法
我们可以新建Kotlin文件,在文件中直接定义方法:
fun kotlinMethod() {
println("call kotlinMethod")
}
如果我们创建的文件名称为:Helper.kt,那么Kotlin编译器会为我们自动创建一个名称为:HelperKt的Java类,kotlinMethod()就是以静态方法定义在HelperKt类里面的。
然后我们就可以在Java代码中愉快的调用了:
class JavaClass {
public void javaMethod(){
kotlinMethod();
}
}
然后我们就可以发现编辑器会导入一个以HelperKt.kotlinMethod结尾的包了。