Kotlin之标准函数和静态方法

1、标准函数

标准函数是指Standard.kt文件中定义的函数,任何Kotlin代码都可以自由的调用所有标准函数,标准函数有很多我们这里主要学习下几个常用的标准函数。

1.1、let函数

let函数提供了函数式API编程接口,并将原始对象作为参数传递到Lambda表达式中,标准的写法如下:

obj.let {
            obj1->需要执行的逻辑
        }

obj1就是obj对象这里写成obj1只是为了防止命名重复的问题,使用的场景如下:

fun doStudy(study: Study?) {
        study?.readBook()
        study?.doHomeWork()
    }

上面代码相当于每次调用Study对象的方法,都需要对study进行判空,我们可以使用let函数配合?.即可解决这个问题。

fun doStudy(study: Study?) {
        study?.let {
            it.readBook()
            it.doHomeWork()
        }
    }

1.2、with函数

with函数接收两个参数:

  • 第一个参数:任意类型的对象
  • 第二个参数:一个Lambda表达式
    with函数会在Lambda表达式中提供第一个参数对象的上下文,并将Lambda表达式最后一行代码作为返回值返回。示例代码如下:
val result=with(obj){
  //这里是obj对象的上下文
“value”//with函数的返回值
}

with函数的作用:它可以在连续调用同一个对象的多个方法时使代码变得简洁。具体示例如下:

val list= listOf<String>("Apple","Banana","Orange","Pear","Grape")
val builder=StringBuilder()
builder.append("Start eating fruit \n")
for(fruit in list){
    builder.append("$fruit \n")
}
builder.append("Ate all fruit")
val result=builder.toString()
println(result)              

仔细观察上面代码,我们多次使用builder对象调用append()进行字符串的拼接,这个时候我们就可以使用with函数来简化这个过程。

val list= listOf<String>("Apple","Banana","Orange","Pear","Grape")
val result=with(StringBuilder()){
    append("Start eating fruit \n")
    for(fruit in list){
        append("$fruit \n")
    }
    append("Ate all fruit")
toString()
}
println(result)

这段代码乍一看有点晕,我们向with()函数中传了2个参数,StringBuilder对象Lambda表达式,传入的StringBuilder对象会作为Lambda表达式的上下文,即我们在Lambda表达式中不再像刚才那样调用builder.append()和builder.toString(),而可以直接调用append()和toString(),并且Lambda表达式的最后一行代码作为with函数的返回值返回。

1.3、run函数

run函数的使用场景和with函数的使用场景一样,只不过用法上有点差别。

  • 1、run函数必须由对象调用。
  • 2、run函数只接受一个参数即Lambda表达式,并将调用对象作为Lambda表达式的上下文。
  • 3、Lambda表达式最后一行代码作为run函数的返回值返回。
    具体示例如下:
val list=listOf("Apple","Banana","Orange","Pear","Grape")
val builder=StringBuilder()
val result=builder.run {
    append("Start eating fruit \n")
    for(fruit in list){
        append("$fruit \n")
    }
    append("Ate all fruits")
    toString()
}

with函数基本一致,只不过是将调用with函数传入StringBuilder对象改成了StringBuilder对象调用run函数。其他没有什么区别。

1.4、apply函数

apply函数和run函数也是极其相似的,都是在某个对象上使用并且只接受一个Lambda表达式参数,调用对象作为Lambda表达式的上下文,不同的是apply函数无法指定返回值,而是返回调用对象本身示例如下:

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

由于apply函数无法指定返回值,只返回调用对象本身,所以这里的result是StringBuilder对象。

1.5、repeat函数

repeat函数接收2个参数,第一个参数是Int类型的,第二个参数Lambda表达式。第一个参数的意思表示的是指Lambda表达式中内容执行的次数。

  val list=ArrayList<String>()
        repeat(2) {
            list.add("1")
            list.add("2")
        }
//集合中的数据就是1,2,1,2

可以看到1,2添加了2遍。

2、定义静态方法

2.1、语法形式上模仿静态方法

在Java中定义静态方法很简单,只需使用static关键字即可。

public static void doAction(){}

在Kotlin中实现静态方法反而没那么简单,实现方式如下:

  • 1、使用单例类实现。
object SIngleInstance {

    fun doAction(){}
}

调用也简单

SIngleInstance.doAction()

看上去是不是和Java中调用静态方法一样,其实Kotlin内部已经创建了唯一的SIngleInstance对象,然后使用对象调用doAction()方法,不过使用单例类的方法就会使类中的所有方法的调用全部变成了类似于静态方法调用的方式了。那么能不能只指定一个或部分方法变成静态方法的调用,这时候就需要companion object了。

  • 2、使用关键字companion object实现
class Util {

    fun doAction1(){

    }

    companion object {
        fun doAction2(){
            println("do action2")
        }
    }
}

普通类Util中有2个方法doAction1()和doAction2(),他们还是有很大区别的,doAction1()的调用必须使用Util类的对象来调用,而doAction2()可以直接使用Util .doAction2()调用。
不过doAction2()其实也不是静态方法,companion object这个关键字实际上会在Util类的内部创建一个伴生类,而doAction2()这个方法就是定义在这个伴生类里面的实例方法,只不过Kotlin保证Util类只会存在一个伴生类对象,因此调用Util.doAction2()实际上调用Util类中伴生类对象的doAction2()。
由此可以看出Kotlin确实没有定义静态方法的关键字,但是提供了一些语法特性来支持静态方法调用的写法。

2.2、确确实实的静态方法

如果想定义实实在在的静态方法,Kotlin提供了两种实现方式:注解和顶层方法
上面我们使用单例类和关键字companion object在语法形式上模仿了静态方法的调用,**我们虽然可以在Kotlin中通过Util.doAction(),但是在Java中是无法这样调用的,因为它并不是真正的静态方法。

  • 1、注解方法实现静态方法
    注解方式实现静态方法只能用在单例类中或companion object关键中,下面我们在companion object关键中加上注解@JvmStatic
companion object {
        @JvmStatic
        fun doAction2(){
            println("do action2")
        }
    }

这样无论在Kotlin中或者Java中我们都能使用Util.doAction2()了,因为此时doAction2()是真正的静态方法了。

  • 2、顶层方法实现静态方法
    顶层方法是指那些没有定义在任何类中的方法,Kotlin编译器会将所有顶层方法编译成静态方法。比如我们在新建的Kotlin FileHelper.kt中定义一个doSomething()方法
fun doSomething() {
    println("do Something")
}
  • 1、在Kotlin中调用很简单,不用管包名路径,也不用创建实例对象,在任意位置都能调用该方法。
  • 2、但是在Java中调用,就不能按Kotlin中这样写否则会报错,在Java中没有顶层方法的概念,所有方法都必须在类中。我们刚才创建的Helper.kt文件,Kotlin编译器就会创建一个HelperKt的Java类,所以在在Java中调用方式为:
HelperKt.doSomething();
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341