函数内联:(预编译指令、宏定义,宏替换)
在JVM上,你定义的lambda会以对象实例的形式存在,JVM会为所有同lambda打交道的变量分配内存,这就产生了内存开销。更糟的是,lambda的内存开销会带来严重的性能问题。幸运的是,kotlin有一种优化机制叫内联,有了内联,JVM就不需要使用lambda对象实例了,因而避免了变量内存分配。哪里需要使用lambda,编译器就会将函数体复制粘贴到哪里。
使用用lambda的递归函数无法内联,因为会导致复制粘贴无限循环,编译会发出警告。
函数引用:
要把函数作为参数传给其他函数使用,除了传lambda表达式,kotlin还提供了其他方法,传递函数引用,函数引用可以把一个具名函数转换成一个值参,使用lambda表达式的地方,都可以使用函数引用。
fun main() {
showOnBoard("笔记本",::getDiscountWords)
}
private fun getDiscountWords(goodsName: String,hour: Int):String{
val currentYear = 2017
return "${currentYear}年,双11${goodsName}促销倒计时$hour 小时"
}
private fun showOnBoard(goodsName: String, getDiscountWords: (String, Int) -> String) {
val hour = (1..24).shuffled().last()
println(getDiscountWords(goodsName, hour))
}
函数类型作为返回类型:
fun main() {
var configDiscountWords = configDiscountWords()
println(configDiscountWords("沐浴露"))
}
fun configDiscountWords(): (String) -> String{
return { goodsName: String ->
val currentYear = 2027
val hour = (1..24).shuffled().last()
"${currentYear}年,双11${goodsName}促销倒计时: $hour 小时"
}
}
闭包:(作用域的保护、Package、Class、模块)
在Kotlin中,匿名函数能修改并引用定义在自己的作用域之外的变量,匿名函数引用着定义自身的函数里的变量,Kotlin中的lambda就是闭包。
能接收函数或者返回函数的函数又叫做高级函数高级函数广泛应用于函数式编程当中。
lambda与匿名内部类:
为什么要在代码中使用函数类型?函数类型能让开发者少写模式化代码,写出更灵活的代码。Java 8支持面向对象编程和lambda表达式但不支持将函数作为参数传给另一个函数或变量,不过Java的替代方案是匿名内部类。
可空性:
对于null值问题,Kotlin反其道而行之,除非另有规定,变量不可为null值,这样一来,运行时崩溃从根源上得到解决。
Kotlin的null类型:(?可空类型)
var str:String? = "butterfly"
str = null
安全调用操作符:(?.)
println(str?.capitalize())
使用带let的安全调用
fun main() {
var str:String? = "butterfly"
str = ""
str?.let {
//非空白的字符串
if(it.isNotBlank()){
it.capitalize()
}else{
"butterfly"
}
}
println(str)
}
非空断言操作符(!!.)
!!.又称感叹号操作符,当变量值为null是,会批出KotlinNullPointerException。
str = null
println(str!!.capitalize())
本文讨论了在Kotlin中使用lambda表达式的内存开销问题,介绍了内联优化如何避免这些开销。同时讲解了函数引用的使用、函数类型作为返回类型、闭包的概念以及Java与Kotlin在可空性和异常处理上的差异,如安全调用操作符和非空断言操作符的应用。
2117





