首页 > 编程语言 >Android第一行代码——快速入门 Kotlin 编程(3.7 Kotlin课堂:标准函数和静态方法)

Android第一行代码——快速入门 Kotlin 编程(3.7 Kotlin课堂:标准函数和静态方法)

时间:2024-03-20 17:32:13浏览次数:13  
标签:调用 静态方法 函数 Kotlin 代码 3.7 run append Lambda

目录

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

3.7.1        标准函数 with、run 和 apply


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

        现在我们即将进入本书首次的 Kotlin 课堂,之后的几乎每一章中都会有这样一个环节。虽说目前你已经可以上手 Kotlin 编程了,但我们只是在第 2 章中学习了一些 Kotlin 的基础知识而已,其实还有许多的高级技巧并没有涉猎。因此每章的 Kotlin 课堂里,我都会结合所在章节的内容,拓展出更多Kotlin 的使用技巧,这将会是你提升自己 Kotlin 水平的绝佳机会。

3.7.1        标准函数 with、run 和 apply

        Kotlin 的标准函数指的是 Standard.kt 文件中定义的函数,任何 Kotlin 代码都可以自由地调用所有的标准函数。

        虽说标准函数并不多,但是想要一次性全部学完还是比较吃力的,因此这里我们主要学习几个最常用的标准函数。

        首先在上一章中,我们已经学习了 let 这个标准函数,它的主要作用就是配合 ? . 操作符来进行辅助判空处理,这里就不再赘述了。

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

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

        那么这个函数有什么作用呢?它可以在连续调用同一个对象的多个方法时让代码变得更加精 简,下面我们来看一个具体的例子。

        比如有一个水果列表,现在我们想吃完所有水果,并将结果打印出来,就可以这样写:

fun main(){
    val list = listOf("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("Ate all fruits.")
    val result = builder.toString()
    println(result)
}

        这段代码的逻辑很简单,就是使用 StringBuilder 来构建吃水果的字符串,最后将结果打印出 来。如果运行一下上述代码,那么一定会得到如 图3.45 所示的打印结果。

图3.45        吃水果字符串的打印结果

        仔细观察上述代码,你会发现我们连续调用了很多次 builder 对象的方法。其实这个时候就可 以考虑使用 with 函数来让代码变得更加精简,如下所示:

fun main(){

    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)
}

        这段代码乍一看可能有点迷惑性,其实很好理解。首先我们给 with 函数的第一个参数传入了一 个 StringBuilder 对象,那么接下来整个 Lambda 表达式的上下文就会是这个 StringBuilder 对象。于是我们在 Lambda 表达式中就不用再像刚才那样调用 builder.append() builder.toString() 方法了,而是可以直接调用 append() toString() 方法。Lambda 表达式的最后一行代码会作为 with 函数的返回值返回,最终我们将结果打印出来。

        这两段代码的执行结果是一模一样的,但是明显第二段代码的写法更加简洁一些,这就是 with 函数的作用。

        下面我们再来学习另外一个常用的标准函数:run 函数。run 函数的用法和使用场景其实和 with 函数是非常类似的,只是稍微做了一些语法改动而已。首先 run 函数通常不会直接调用, 而是要在某个对象的基础上调用;其次 run 函数只接收一个 Lambda 参数,并且会在 Lambda 表达式中提供调用对象的上下文。其他方面和 with 函数是一样的,包括也会使用 Lambda 表达式中的最后一行代码作为返回值返回。示例代码如下:

val result = obj.run { 
    // 这里是obj的上下文
    "value" // run函数的返回值
} 

        那么现在我们就可以使用 run 函数来修改一下吃水果的这段代码,如下所示:

fun main(){
//    run 写法
    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)
}

        总体来说变化非常小,只是将调用 with 函数并传入 StringBuilder 对象改成了调用 StringBuilder 对象的 run 方法,其他都没有任何区别,这两段代码最终的执行结果是完全相同的。

        最后我们再来学习标准函数中的 apply 函数。apply 函数和 run 函数也是极其类似的,都要在某个对象上调用,并且只接收一个 Lambda 参数,也会在 Lambda 表达式中提供调用对象的上下文,但是apply函数无法指定返回值,而是会自动返回调用对象本身。示例代码如下:

val result = obj.apply { 
    // 这里是obj的上下文
} 
// result == obj 

        那么现在我们再使用 apply 函数来修改一下吃水果的这段代码,如下所示:

fun main(){
//    apply 写法
    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())
}

        注意这里的代码变化,由于 apply 函数无法指定返回值,只能返回调用对象本身,因此这里的 result 实际上是一个 StringBuilder 对象,所以我们在最后打印的时候还要再调用它的 toString()方法才行。这段代码的执行结果和前面两段仍然是完全相同的,我就不再重复演示了。

        这样我们就将 Kotlin 中最常用的几个标准函数学完了,你会发现其实 withrun apply 这几个函数的用法和使用场景是非常类似的。在大多数情况下,它们可以相互转换,但你最好还是 要掌握它们之间的区别,以便在编程时能够作出最佳的选择。

        回想一下刚刚在最佳实践环节编写的启动 Activity 的代码:

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

        这里每传递一个参数就要调用一次 intent.putExtra() 方法,如果要传递 10 个参数,那就得 调用 10 次。对于这种情况,我们就可以使用标准函数来对代码进行精简,如下所示:

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

        可以看到,由于Lambda 表达式中的上下文就是Intent 对象,所以我们不再需要调用 intent.putExtra() 方法,而是直接调用 putExtra() 方法就可以了。传递的参数越多,这 种写法的优势也就越明显。 

        好了,关于Kotlin 的标准函数就讲到这里,本书后面的章节中还将会有大量使用标准函数的代码 示例,到时候你会对它们掌握得越来越熟练。

小贴士:

let 函数,它的主要作用就是配合 ? . 操作符来进行辅助判空处理

with 函数接收两个参数:

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

        第二个参数是一个 Lambda 表达式

run 函数通常不会直接调用, 而是要在某个对象的基础上调用;

        其次 run 函数只接收一个 Lambda 参数,

                并且会在 Lambda 表达式中提供调用对象的上下文。

        其他方面和 with 函数是一样的

apply 函数要在某个对象上调用,

                只接收一个 Lambda 参数

                在 Lambda 表达式中提供调用对象的上下文

                自动返回调用对象本身

标签:调用,静态方法,函数,Kotlin,代码,3.7,run,append,Lambda
From: https://blog.csdn.net/fhbxts/article/details/136881105

相关文章

  • Android第一行代码——快速入门 Kotlin 编程(3.6 Activity 的最佳实践)
    目录3.6        Activity的最佳实践3.6.1    知晓当前是在哪一个Activity3.6.2    随时随地退出程序 3.6.3    启动Activity的最佳写法3.6        Activity的最佳实践        关于Activity,你已经掌握了非常多......
  • FPGA设计优化(3.7)
            设计规则1:对综合后的设计就要开始进行扇出分析,以尽早发现高扇出的网线,并评估其可能对设计造成的影响。report_high_fanout_nets的具体用法如Tcl代码9-1所示。代码第3行的选项-load_types生成的报告样例如图9-1所示。从此报告中可以看到网线rectify_reset的扇出......
  • Kotlin 协程基础使用学习
    原文:Kotlin协程基础使用学习-Stars-One的杂货小窝本篇阅读可能需要以下知识,否则可能阅读会有些困难客户端开发基础(Android开发或JavaFx开发)Java多线程基础kotlin基础本文尽量以使用为主,以代码为辅讲解,不提及过深协程底层代码逻辑,仅做一个基础入门来快速上手学习......
  • Android第一行代码——快速入门 Kotlin 编程(2.5 面向对象编程)
    目录2.5    面向对象编程2.5.1    类与对象2.5.2    继承与构造函数2.5.3    接口2.5.4    数据类与单列类2.5    面向对象编程        和很多现代高级语言一样,Kotlin也是面向对象的,因此理解什么是面向对......
  • PW2058降压芯片:3.7V至3V快速转换,低功耗设计,外围电路简洁
    概述:在便携式设备日益普及的今天,高效、稳定的电源管理成为了关键。PW2058作为一款恒频、电流模式降压转换器,以其出色的性能和广泛的应用范围,成为了市场上备受瞩目的产品。它集成了主开关和同步整流器,无需额外添加肖特基二极管,即可实现高达96%的效率,为单电池锂离子电池供电的便携......
  • python3.7.4 RV1126 交叉编译
    首先,十分感谢大佬分享的交叉编译攻略,原文链接如下:https://www.cnblogs.com/Se7eN-HOU/p/16736164.html在此基础上,本人经过一周时间的踩坑,终于在RV1126开发板上实现了交叉编译。现记录本人实际编译版本与上述版本略有不同之处。主要是由于3.5.2版本的python和openssl1.0.2g在......
  • 3. 寄存器(内存) | 问题 3.7 - 3.10
    问题3.7编程,将10000H  ~  1000FH做为连本带利,初始状态是空的,将AX,BX,DS中的数据入栈。#初始化SS,SPss=1000H[sp]=[0010],则[ssss:sp]=[1000H:0010H]movax,1000movss,ax#sp是指针,不是段寄存器,可以直接传数据,不用ax中转movsp,0010pushaxpushbxpu......
  • 锂电池电源转换利器:PW2053芯片,实现3.7V转3V/2.5V/1.2V低功耗转换
    在现代电子设备领域,高效、稳定的电源管理对于设备的性能和寿命至关重要。特别是在锂电池供电的应用中,选择一款性能卓越的降压调节器显得尤为关键。今天,我们将向您介绍一款备受赞誉的高效同步降压调节器——PW2053。这款调节器凭借其出色的性能和广泛的应用领域,在电源管理领域独领......
  • 2024.3.7习题总结
    CF1288C题目可以把\(a\)数组和\(b\)数组的倒序合并,这样,题目就成了求出长度为\(2m\)的序列递增的方案数,\(dp\)求解可以把长度为\(2m\)的差分数组。对于任意一个\(c_i\),\(c_i\ge0,\sumc_i\len\),所以方案数为\(C_{n+2*m-1}^{2*m}\)CF1569C......
  • 3.7
     第一天第二天第三天第四天第五天所花时间(包括上课)6h上课3h学安卓4.5h   代码量(行)70230行   博客量(篇)11   了解到的知识点Android创建第一个项目,创建第一个活动,安装matlab,PyCham学会toast用法学会intent跳转活动和传......