标准函数with、run、apply等和静态方法

一、标准函数

Kotlin的标准函数有很多,先学习常用的with、run、apply三个。

还有let标准函数,主要是配合 ?. 操作符进行判空处理,以保证线程安全。

标准函数with:

with函数接收两个参数:

第一个参数可以是任意类型的对象。

第二个参数是一个Lambda表达式,表达式中提供参数对象的上下文,即参数对象所在的场景,并使用Lambda表达式中的最后一行作为返回值。

使用格式为:

val res = with(obj){
    //obj的上下文,要做的事
    "value"   //with的返回值
}

具体使用场景:当我们需要连续调用同一个对象的多种方法时,可以使代码更加简洁。例如,正常些一个吃水果的代码:

fun main() {
    val list = mutableListOf<String>("Apple", "Banana", "Orange", "Pear", "Grape")
    val builder = StringBuilder()
    builder.append("Start eating fruits:\n")
    for (fruit in list) {
        builder.append(fruit).append('\n')
    }
    builder.append("You have eat all fruits!")
    val res = builder.toString()
    println(res)
}

代码中,我们连续调用了builder对象的很多函数方法,可以考虑使用with来进行简化,简化代码:

    val res2 = with(builder) {
        append("Start eating fruits:\n")
        for (fruit in list) {
            append(fruit).append('\n')
        }
        append("You have eat all fruits!")
        toString()
    }
    println(res2)

根据with函数的使用格式,分析可知:

给with传入了一个StringBuilder对象,接下来整个Lambda表达式的上下文就是这个StringBuilder对象,这个builder对象会以 this对象形式 被传入到Lambda表达式,就不需要像之前builder.append()这样进行操作,直接调用append函数即可,其它的函数像toString()类似,都不需要对象进行调用。

进一步简化了代码。

标准函数run:

run()函数和with()函数区别不大,with()函数需要传入一个参数,然后以这个参数作为上下文进行操作。run()函数不需要传入参数,但是他需要在一个对象的基础上进行操作,他的使用格式如下:

val res = obj.run{
    //obj的上下文
    "value" //返回结果
}

从使用格式上看,与with()函数区别不大,Lambda表达式内的写法两者具有一致性。

使用run函数来更改上述吃水果的代码如下:

    val res3 = builder.run {
        append("Start eating fruits:\n")
        for (fruit in list) {
            append(fruit).append('\n')
        }
        append("You have eat all fruits!")
        toString()
    }
    println(res3)

只是将调用with函数并传入StringBuilder对象改成了调用StringBuilder对象的run方法,其它代码保持不变。

标准函数apply:

apply()函数和run()函数相似,都不需要传入参数,都需要在某个函数上调用,并且只接收一个lambda表达式,也会在Lambda表达式中提供该对象的上下文。但是apply()函数不返回值,而是会自动返回该对象本身。apply()函数的使用格式如下:

val res = obj.apply{
    //obj的上下文
}
//res == obj

使用apply()函数来更改上述吃水果代码如下:

    val res4 = builder.apply {
        append("Start eating fruits:\n")
        for (fruit in list) {
            append(fruit).append('\n')
        }
        append("You have eat all fruits!")
    }
    println(res4.toString())

想起之前在向intent中传递数据的代码,可以简化更改为:

val intent = Intent(context, SecondActivity::class.java).apply {
    putExtra("data1", param1)
    putExtra("data2", param2)
}

由于intent并不需要返回值,这里使用apply()函数来进行简化。

二、静态方法

Kotlin不同于java,java中定义静态方法,一般会在类中,使用static关键字来定义静态方法,使得该静态方法能够在不创建类的实例对象时,可以直接通过类名调用。例如:

public class Util {
    public static void doSomeThing() {
        System.out.println("Let's do something!");
    }
}

这就是一个简单的工具类,工具类没有创建实例对象的必要,而且全局通用。

在Kotlin中,定义一个工具类,一般使用单例类来进行创建,上述代码在Kotlin中变为:

object Unit{
    fun doSomeThing() {
        println("Let's do something!")
    }
}

将Unit定义为object类型,声明它是单例类。

这虽然不是静态方法,但是仍旧可以使用Unit.doSomeThing()来调用,和静态方法类似。

但是,使用这种方法,这样会导致这个类的所有方法都是工具类,当我们只想让类的某一个函数成为静态方法时,需要使用 companion object 方法。这相当于在类中创建了一个伴生类,而Kotlin会保证该类中只有这一个伴生类。代码如下:

class Unit{

    fun doAction() {
        println("do action!")
    }

    companion object{
        fun doSomeThing() {
            println("Let's do someThing!")
        }
    }
}

这里声明了Unit是普通class类,然后使用companion object创建了该类的伴生类,可直接通过该类名调用伴生类中的函数,即 Unit.doSomeThing()。

单例类和companion object都只是在语法的形式上模仿了静态方法的调用方式,实际上它们都不是真正的静态方法。因此如果你在Java代码中以静态方法的形式去调用这些方法的话,你会发现这些方法并不存在。

Kotlin为构建静态方法提供了两种方式:注解和顶层

注解:

如果我们给刚才的单例类或companion object中的方法加上@JvmStatic注解,那么Kotlin编译器就会将这些方法编译成真正的静态方法,例如;

class Unit{

    fun doAction() {
        println("do action!")
    }

    companion object{
        @JvmStatic
        fun doSomeThing() {
            println("Let's do someThing!")
        }
    }
}

这样doSomeThing() 就成了静态方法。那么现在不管是在Kotlin中还是在Java中,都可以使用Util.doAction2()的写法来调用了。

顶层:

顶层方法指的是那些没有定义在任何类中的方法,比如我们编写的main()方法。Kotlin编译器会将所有的顶层方法全部编译成静态方法,因此只要你定义了一个顶层方法,那么它就一定是静态方法。

重新创建一个空的Kotlin文件,例如叫做TopFun.kt,文件中没有任何类,只有fun 定义的函数,这就是顶层方法。这个文件中的所有方法都是静态方法,可以全局调用。

但如果是在Java代码中调用,你会发现是找不到使用顶层方法定义的这些静态方法的,因为Java中没有顶层方法这个概念,所有的方法必须定义在类中。

我们刚才创建的Kotlin文件名叫作TopFun.kt,于是Kotlin编译器会自动创建一个叫作TopFunkt的Java类,其中的方法就是以静态方法的形式定义在TopFunkt类里面的,因此在Java中直接使用TopFunkt.fun()的写法来调用就可以了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值