IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Twitter 上有趣的代码 -> 正文阅读

[移动开发]Twitter 上有趣的代码

320.08-Twitter 上有趣的代码

全文分为 视频版文字版

  • 文字版: 文字侧重细节和深度,有些知识点,视频不好表达,文字描述的更加准确
  • 视频版: 视频以动画的形式会更加的直观,看完文字版,在看视频,知识点会更加清楚,Twitter 上有趣的代码_哔哩哔哩_bilibili

这是海外一位 Kotlin GDE 大佬,在 Twitter 上分享的一段代码,我觉得非常的有意思,代码如下所示,我们花 10s 思考一下,输出结果是什么。

fun printE() = { println("E") }

fun main() {
    if (true) println("A")
    if (true) { println("B") }
    if (true) {
        { println("C") }
    }
    
    { println("D") }
    
    printE()
    
    when {
        true -> { println("F") }
    }
}

在 Twitter 评论区中也能看到很多不同的答案。

pic02

实际上最后输出结果如下所示。

A
B
F

不知道你第一次看到这么多混乱的花括是什么感觉,当我第一次看到这段代码的时候,我觉得非常的有意思。

如果在实际项目中有小伙伴这么嵌套花括号,我相信肯定会被拉出去暴晒。但是细心观察这段代码,我们能学习到很多 Kotlin 相关的知识点,我们先来说一下为什么最后输出的结果是 A B F

下面图中红色标注部分,if 表达式、 when ... case 表达,如果表达式内只有一行代码的话,花括号是可以省略的,程序执行到代码位置会输出对应的结果, 即 A B F

那为什么 C D E 没有打印,因为图中绿色部分是 lambda 表达式,在 Kotlin 中 lambda 表达式非常的自由,它可以出现在很多地方比如方法内、 if 表达式内、循环语句内、甚至赋值给一个变量、或者当做方法参数进行传递等等。

lambda 表达式用花括号包裹起来,用箭头把实参列表和 lambda 函数体分离开来,如下所示。

{ x: Int -> println("lambda 函数体") }

如果没有参数,上面的代码可以简写成下面这样。

{ println("lambda 函数体") }

C D E 的输出语句在 lambda 函数体内, lambda 表达式我们可以理解为高阶函数,在上面的代码中只是声明了这个函数,但是并没有调用它,因此不会执行,自然也就不会有任何输出。现在我将上面的代码做一点点修改,在花 10s 思考一下输出结果是什么。

fun printE() = { println("E") }

fun main() {
    if (true) println("A")
    if (true) { println("B") }
    if (true) {
        { println("C") }()
    }

    { println("D") }()

    printE()()

    when {
        true -> { println("F") }
    }
}

最后的输出结果是:

A
B
C
D
E
F

应该有小伙伴发现了我做了那些修改,我只是在 lambda 表达式后面加了一个 (),表示执行当前的 lambda 表达式,所以我们能看到对应的输出结果。如下图所示,

lambda 表达式最终会编译成 FunctionN 函数,如下图所示。

如果没有参数会编译成 Function0,一个参数编译成 Function1,以此类推。FunctionN 重载了操作符 invoke。如下图所示。

因此我们可以调用 invoke 方法来执行 lambda 表达式。

{ println("lambda 函数体") }.invoke()

当然 Kotlin 也提供了更加简洁的方式,我们可以使用 () 来代替 invoke(),最后的代码如下所示。

{ println("lambda 函数体") }()

到这里我相信小伙伴已经明白了上面代码输出的结果,但是这里隐藏了一个有性能损耗的风险点,分享一段我在实际项目中见到的代码,示例中的代码,我做了简化。

fun main() {
    val count = 2
    (1..10).forEach { value ->
        calculate(value) { result ->
            val average = result / count
            println(average)
        }
    }

}


fun calculate(x: Int, lambda: (result: Int) -> Unit) {
    lambda(x + 10)
}

上面的代码其实存在一个比较严重的性能问题,我们看一下反编译后的代码。

每次在循环中都会创建一个 FunctionN 的对象,那么如何避免这个问题,我们可以将 lambda 表达式放在循环之外,这样就能保证只会创建一个 FunctionN 对象,我们来看一下修改后的代码。

fun calculate(x: Int, lambda: (result: Int) -> Unit) {
    lambda(x + 10)
}

fun main() {
    val count = 2
    val lambda: (result: Int) -> Unit = { result ->
        val average = result / count
        println(average)
    }
    (1..10).forEach { value ->
        calculate(value, lambda)
    }
}

全文到这里就结束了,感谢你的阅读,坚持原创不易,欢迎在看、点赞、分享给身边的小伙伴,我会持续分享原创干货!!!



近期必读热门文章

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-09-24 21:08:24  更:2022-09-24 21:09:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 5:39:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码