Hola a todos, mi nombre es DHL. Cuenta pública: ByteCode, que se centra en compartir contenido original e interesante, Kotlin, Jetpack, optimización del rendimiento, código fuente del sistema, algoritmo y estructura de datos, animación, gran experiencia de fábrica
El texto completo se divide en versión de video y versión de texto .
- Versión de texto : el texto se centra en los detalles y la profundidad, algunos puntos de conocimiento, el video no es fácil de expresar, la descripción del texto es más precisa
- Versión en video: El video será más intuitivo en forma de animación.Después de leer la versión de texto, mientras miras el video, los puntos de conocimiento serán más claros.Códigos interesantes en Twitter
Este es un fragmento de código compartido por un jefe de Kotlin GDE en el extranjero en Twitter. Creo que es muy interesante. El código es el siguiente. Pasemos 10 segundos pensando en el resultado de salida.
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") }
}
}
复制代码
También se pueden ver muchas respuestas diferentes en la sección de comentarios de Twitter.
De hecho, el resultado final es el siguiente.
A
B
F
复制代码
No sé cómo te sientes cuando ves tantas llaves desordenadas por primera vez, cuando vi este código por primera vez, pensé que era muy interesante.
Si hay socios pequeños anidando llaves como esta en el proyecto real, creo que definitivamente serán sacados y expuestos al sol. Pero observando cuidadosamente este código, podemos aprender muchos puntos de conocimiento relacionados con Kotlin, hablemos de por qué el resultado final es A B F
.
La parte marcada en rojo en la figura a continuación, if
expresión, when ... case
expresión, si solo hay una línea de código en la expresión, se pueden omitir los corchetes y el programa generará el resultado correspondiente cuando el programa se ejecute en la posición del código, es decir 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)
}
}
复制代码
全文到这里就结束了,感谢你的阅读,坚持原创不易,欢迎在看、点赞、分享给身边的小伙伴,我会持续分享原创干货!!!
真诚推荐你关注我,公众号:ByteCode ,持续分享硬核原创内容,Kotlin、Jetpack、性能优化、系统源码、算法及数据结构、动画、大厂面经。
近期必读热门文章
- 谁动了我的内存,揭秘 OOM 崩溃下降 90% 的秘密
- 反射技巧让你的性能提升 N 倍
- 90%人不懂的泛型局限性,泛型擦除,星投影
- 90%的人都不知道的知识点,Kotlin 和 Java 的协变和逆变
- CPU 如何记录函数调用过程和返回过程
- 揭秘反射真的很耗时吗,射 10 万次耗时多久
- 揭秘 Kotlin 1.6.20 重磅功能 Context Receivers
- Stack Overflow 上最热门的 10 个 Kotlin 问题
- Android 12 已来,你的 App 崩溃了吗?
- Google 宣布废弃 LiveData.observe 方法
- 影响性能的 Kotlin 代码(一)
- 揭秘 Kotlin 中的 == 和 ===
最后推荐长期更新和维护的项目
-
个人博客,将所有文章进行分类,欢迎前去查看 hi-dhl.com
-
KtKit 小巧而实用,用 Kotlin 语言编写的工具库,欢迎前去查看 KtKit
-
Planeamos establecer un proyecto práctico de los componentes y artículos relacionados con AndroidX Jetpack más completos y más recientes sobre el análisis principal de los componentes relacionados. Estamos agregando gradualmente nuevos miembros de Jetpack, y el almacén se actualiza continuamente. Bienvenido a consultar AndroidX-Jetpack- Práctica
-
LeetCode / Oferta de esgrima / Preguntas de entrevistas de fabricantes nacionales y extranjeros / Soluciones de problemas de subprocesos múltiples, lenguaje Java y kotlin, incluida una variedad de soluciones, ideas para resolver problemas, complejidad de tiempo, análisis de complejidad de espacio
- La espada se refiere a la oferta y las preguntas de la entrevista de fabricantes nacionales y extranjeros: lectura en línea
- Serie de preguntas LeetCode: lectura en línea