Kotlin 的学习笔记

 let 函数

源码:

fun <T, R> T.let(block: (T) -> R): R {
    return block(this)
}

作用:对一个对象执行一段代码块,并返回代码块的执行结果

使用场景:空安全处理 + 代码简化

1. 替代繁琐的 if 判空

不用 let 的写法(Java 风格)

val str: String? = "Hello Kotlin"
if (str != null) {
    println("字符串长度:${str.length}")
}

用 let + ?. 的写法(Kotlin 风格)

val str: String? = "Hello Kotlin"
str?.let { 
    println("字符串长度:${it.length}") 
}
  • 这里的 ?. 表示:如果 str 为 null,就不执行后面的 let;如果非 null,就把 str 传给 let 的 lambda。
  • lambda 中的 it 指代非 null 的 str(非空的调用者本身),可以安全调用 length 方法。
2. 链式处理可空对象的属性 / 方法

不用 let 的写法

data class User(val address: Address?)
data class Address(val city: String?)

val user: User? = User(Address("Shanghai"))

// 层层判空,嵌套多
if (user != null) {
    val address = user.address
    if (address != null) {
        val city = address.city
        if (city != null) {
            println("城市:$city")
        }
    }
}

用 let + ?. 的链式写法

user?.address?.city?.let { city ->
    println("城市:$city")
}
3:临时变量重命名,避免歧义

当 lambda 中需要多次使用接收者对象,或者存在嵌套时,it 可能会显得模糊。这时可以给 it 自定义命名,提高可读性。

val book: Book? = Book("Kotlin 实战", 89.0)

book?.let { bookObj ->  // 自定义变量名 bookObj,代替 it
    println("书名:${bookObj.title}")
    println("价格:${bookObj.price}")
}
4:作为函数返回值,简化条件判断

let 的返回值是 lambda 最后一行的结果,因此可以直接用于函数返回,避免临时变量。

例如,定义一个函数,返回字符串的长度(若为 null 则返回 0):

fun getStringLength(str: String?): Int {
    // 若 str 非 null,返回 it.length;否则返回 0
    return str?.let { it.length } ?: 0
}

注意: ?:的作用是:如果it.length 的结果为空,则返回 :右边的值0

with 函数

使用方式:

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

伪代码:

val result = with(obj) {

// 这里是obj的上下文

"value" // with函数的返回值

}

作用:可以在连续调用同一个对象的多个方法时让代码变得更加精简

案例:打印水果

不使用 with 函数:

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)

使用 with 函数 (注意 with 函数最后一行为返回值,所以要提前调用 toString 函数)

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)

run 函数

使用方式和作用:和 with 类似

打印水果案例使用 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)

apply 函数

用法和作用与 run类似,区别在于 apply函数无法指定返回值,而是会自动返回调用对象本身。

打印水果案例使用 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())

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐