Kotlin 提供了大量语法糖,让代码更简洁、更安全、更易读。以下是开发中最常用的一些语法糖,附代码示例和使用说明。
1. let -- 作用域函数
let 是一个作用域函数,它将调用者作为参数(it)传入代码块,并返回代码块的最后一行结果。常用于安全调用 和限定变量作用域。
基本用法
kotlin
val name: String? = "Kotlin"
name?.let {
println("Name length: ${it.length}") // it 是非空的 name
}
链式处理
kotlin
val result = listOf(1, 2, 3)
.map { it * 2 }
.filter { it > 2 }
.let {
println("Processed list: $it")
it.sum()
} // 返回 sum
典型场景:避免重复判断空值
kotlin
// 传统写法
if (user != null && user.address != null) {
println(user.address.street)
}
// 使用 let
user?.address?.let { addr ->
println(addr.street)
}
2. in -- 范围检查与集合成员判断
in 用于检查一个值是否在某个范围 内,或者是否属于某个集合 。对应的否定形式是 !in。
范围检查
kotlin
val score = 85
if (score in 60..100) {
println("及格")
}
// until:不包含上界
for (i in 0 until 10) { // 0..9
print("$i ")
}
// downTo:递减
for (i in 10 downTo 1) {
print("$i ")
}
集合成员判断
kotlin
val list = listOf("apple", "banana", "cherry")
if ("banana" in list) {
println("Found")
}
val map = mapOf(1 to "one", 2 to "two")
if (1 in map) { // 检查 key 是否存在
println(map[1])
}
when 表达式中使用
kotlin
when (x) {
in 1..10 -> println("1~10")
in 11..20 -> println("11~20")
else -> println("Other")
}
3. as? -- 安全类型转换(慎用 as)
as? 用于安全类型转换 :如果转换失败,返回 null,而不是抛出 ClassCastException。
对比 as
kotlin
val obj: Any = "Hello"
// ❌ 不安全的 as:转换失败会抛异常
val num = obj as Int // ClassCastException
// ✅ 安全的 as?:失败返回 null
val numSafe = obj as? Int // null
推荐:总是使用 as? 除非你 100% 确定类型
kotlin
fun getStringLength(obj: Any): Int? {
// obj as? String 返回 String? 类型
return (obj as? String)?.length
}
⚠️ 慎用
as:不加?的强制转换一旦类型不匹配就会崩溃。只有在你完全确定类型,且失败应该被视为严重 bug 时才用as(例如在框架内部的类型擦除补救)。日常代码中优先使用as?+ 空处理。
4. is -- 类型检查(智能转换)
is 用于检查一个对象是否是指定类型(或其子类型)。配合 !is 检查否定。一旦通过 is 检查,Kotlin 编译器会自动智能转换为该类型,无需显式强转。
基本用法
kotlin
fun printLength(obj: Any) {
if (obj is String) {
// 此处 obj 自动转换为 String 类型
println(obj.length) // 不需要 (obj as String).length
}
}
when + is
kotlin
fun describe(obj: Any) = when (obj) {
is String -> "String of length ${obj.length}"
is Int -> "Integer"
is Boolean -> "Boolean"
else -> "Unknown"
}
可空类型的智能转换
kotlin
val str: String? = "Kotlin"
if (str is String) { // 实际上 is String 已经排除了 null
println(str.length) // 智能转换为非空 String
}
5. until -- 开区间范围
until 用于创建一个不包含上界 的整数范围。常用于循环,代替 0..n-1。
基本用法
kotlin
for (i in 0 until 10) { // 0..9
print("$i ")
}
与 .. 对比
kotlin
// .. 包含上界
for (i in 0..5) print(i) // 0 1 2 3 4 5
// until 不包含上界
for (i in 0 until 5) print(i) // 0 1 2 3 4
常见场景:遍历数组索引
kotlin
val arr = arrayOf("a", "b", "c")
for (i in arr.indices) { // indices 内部使用了 until
println(arr[i])
}
// 等价于
for (i in 0 until arr.size) { ... }
6. downTo -- 递减范围
downTo 创建一个递减的整数范围,常用于反向循环。
基本用法
kotlin
for (i in 10 downTo 1) {
print("$i ") // 10 9 8 ... 1
}
指定步长
kotlin
for (i in 10 downTo 1 step 2) {
print("$i ") // 10 8 6 4 2
}
遍历列表反向
kotlin
val list = listOf("a", "b", "c")
for (i in list.lastIndex downTo 0) {
println(list[i]) // c, b, a
}
7. ?. -- 安全调用操作符
?. 是空安全调用的核心语法。如果接收者不为 null,则调用属性或方法;否则直接返回 null,不会抛出 NullPointerException。
基本用法
kotlin
val str: String? = "Kotlin"
val len = str?.length // 返回 Int? = 5
val nullStr: String? = null
val len2 = nullStr?.length // 返回 null,不会崩溃
链式安全调用
kotlin
class Address(val street: String)
class User(val address: Address?)
val user: User? = User(Address("Main St"))
val street = user?.address?.street // 任何一个为 null,结果就是 null
结合 let 执行非空代码块
kotlin
user?.let {
println(it.address) // 仅当 user 不为 null 时执行
}
与 ?:(Elvis 操作符)配合提供默认值
kotlin
val length = str?.length ?: 0 // 如果 str 为 null,则用 0
总结表格
| 语法糖 | 作用 | 示例代码 |
|---|---|---|
let |
作用域函数,安全执行非空逻辑 | name?.let { println(it.length) } |
in |
检查属于范围或集合 | if (x in 1..10), if ("ok" in list) |
as? |
安全类型转换(失败返 null) | val num = obj as? Int |
is |
类型检查 + 智能转换 | if (obj is String) println(obj.length) |
until |
开区间范围(不含上界) | for (i in 0 until size) |
downTo |
递减范围 | for (i in 10 downTo 1) |
?. |
安全调用,避免空指针 | val len = str?.length |
这些语法糖是 Kotlin 日常开发中使用频率最高的,熟练掌握它们能显著提升编码效率和代码可读性。