3.7–Kotlin 课堂:标准函数和静态方法

2023年1月31日09:28:38

3.7.1 标准函数 with、run和apply

Kotlin 的标准函数指的是 Standara.kt 文件中定义的函数,任何Kotlin  代码都可以自由调用所有的标准函数。我们已经学习了let 标准函数 ,let 标准函数的主要作用就是配合.? 进行辅助判空处理。

下面我们学习新的 标准函数with。with 函数接收两个参数,第一个参数可以是一个任意类型的对象,第二个参数是Lambda表达式。with 函数会在Lambda 表达式中提供第一个参数对象的上下文,并使用Lambda 表达式的最后一行代码作为返回值返回。

with(obj){
            // 这里是 ojb 的上下文
            "value" // with 函数的返回值
        }

这个函数可以让连续调用同一个对象的多个方法时让代码变得更加精简!

我们举个例子,例如创建一个水果列表,将水果列表全部打印出来:

fun printFruits(){
        val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")
        val buffer = StringBuilder()
        buffer.append("Start eating fruits. \n")
        for (fruit in list) {
            buffer.append(fruit).append("\n")
        }
        buffer.append("Ate all fruits.")
        val result = buffer.toString()
        println(result)
    }

我们会得到的打印结果为

观察上面的代码我们可以看到多次调用了builder 对象的方法,其实这个时候就可以使用with 函数来让代码变得更加简单

fun printFruits(){
    val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")
    val result = with(StringBuilder()) {
        append("Start eating fruits. \n")
        for (fruit in list) {
            append(fruit).append("\n")
        }
        append("Ate all fruits.")
        toString()
    }
    println(result)
}

代码乍一看有点迷,这个append 方法怎么来的? 我们在上面介绍了,with 第一个参数传入的是任意对象也就是StringBuilder ,而第二个参数是一个Lambda 表达式,with 函数会在Lambda 表达式中提供第一个参数对象的上下文 , 这个上下文就是环境的意思,我们就可以调用这个上下文对象内置的方法函数了。也就是说我们在第一个参数传入了什么对象,那么Lambda 表达式内就会拥有这个对象的所有变量和函数,就相当于在对象内部调用函数,所以我们直接调用了StringBuilder 对象的append 函数。

接下来我们继续学习另外一个常用的标准函数 run 函数,这个函数和with 作用几乎是一模一样的,就是结构不同,with 函数是内置函数形式调用with(obj){} ,run 函数是 obj.run{} ,一个是通过传入对象,一个是通过对象调用,作用相同,也是Lambda表达式内包含上下文环境,最后一句代码为返回值,run 函数只有一个参数就是Lambda 表达式。我们来修改一下上面的代码:

fun printFruits(){
    val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")
    val result = StringBuilder().run {
        append("Start eating fruits. \n")
        for (fruit in list) {
            append(fruit).append("\n")
        }
        append("Ate all fruits.")
        toString()
    }
    println(result)
}

接下来学习本小节的最后一个函数 apply 函数,apply 函数和 run 函数基本相同,不同的地方在于,apply 会返回对象本身,Lambda 表达式内不存在返回值,也是在Lambda 表达式中提供对象的上下文,结构为 obj.apply{}。我们来修改一下代码:

fun printFruits(){
    val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")
    val result = StringBuilder().apply {
        append("Start eating fruits. \n")
        for (fruit in list) {
            append(fruit).append("\n")
        }
        append("Ate all fruits.")
    }
    println(result.toString())
}

可以看出来我们删掉了otString() 而在输出的时候 调用了 result.toString(),因为返回的是StringBuilder 对象的本身。

这里我们就可以修改一下之前我们启动Activity 的代码了!

companion object{
        fun actionStart(context:Context,data1:String,data2:String){
            val intent = Intent(context,SecondActivity::class.java).apply {
                putExtra("param1",data1)
                putExtra("param2",data2)
            }
            context.startActivity(intent)
        }
    }

怎么样?是不是又精简了很多。

3.7.2 定义静态方法

Java 中定义静态方法很简单,只需要在方法 返回值关键字前添加static 修饰符即可,通过类名.方法名调用。例如:

public class Util {
    public static void doAction(){
        System.out.println("do action");
    }
}

我们在Kotlin 中是没有这个static 修饰符的,Kotlin 极度弱化了静态方法的概念,我们想要在一个类中定义一个静态方法反倒是一件麻烦的事,因为Kotlin 提供了一个更好的语法特性,单例类。

object Util {
    fun doAction(){
        println("do action")
    }
}

单例类的特性是在第一次调用的时候会创建这个类,其调用函数的方式和调用静态类中的调用方式相同。但是如果我们想要在一个非单例类中调用一个静态方法怎么办?就类似之前我们写的启动Activity 方式,这就运用到了companion object了,由于之前都已经使用过了,这里直接解释原理。

companion object  会代码块内的函数和变量会直接被编译成静态的,但是一个类 使用了companion object 关键字后,那么这个类就会创建一个伴生类,类似于 匿名内部类 ,既然类似于匿名内部类 ,那么就可以去继承其他的类:

class Util {
    fun doAction(){
        println("do action1")
    }
    companion object:Father(){
        fun doAction1(){
            println("do action2")
        }
    }
}

但是如果在Java 中以静态方法的形式调用,会发现这个方法并不存在,因为在伴生类中所以编译会有差异,如果我们在companion object 内部函数上添加@jvmStatic 注解,那么Kotlin 编译器就会将这个方法编译成真正的静态方法!

class Util {
    fun doAction(){
        println("do action1")
    }
    companion object:Father(){
        @JvmStatic
        fun doAction1(){
            println("do action2")
        }
    }
}

这样添加注解后使用Java 代码也可以调用了。

另外我们定义的顶层方法也是会被编译成静态方法的,什么是顶层方法呢?就是在 类外面定义的方法,就如同我们在Kotlin 中间中定义的main 方法一样,只要定义了这种函数,我们在Kotlin 中的任意类或者文件都是直接可以调用的,不用管包名,不用管路径,也不用创建实例 ,直接键入 函数即可。但是在Java 中不存在顶层函数的概念,会找不到这个函数的,Java 需要通过文件名Kt.函数名的方式调用。

public void quote(){
        KotlinKt.printFruits();
    }

任何有顶层函数的class 文件 都会变成.kt 文件哦。

 

  • 作者:csdn_DaShuiNiu
  • 原文链接:https://blog.csdn.net/CSDN_DaShuiNiu/article/details/106026768
    更新时间:2023年1月31日09:28:38 ,共 3435 字。