Kotlin官方文档-基础知识-常用惯用语法(翻译官方文档+自我总结)

本文汇总了 Kotlin 中一些实用且常用的惯用语法。如果您有常用的惯用语法,可通过提交拉取请求(pull request)补充。

官方文档地址

(注:文档翻译部分由 AI 完成)

1.创建数据传输对象(DTOs,即 POJOs/POCOs)

kotlin 复制代码
data class Customer(val name: String, val email: String)

上述代码定义的 Customer 类自动具备以下功能:

  • 所有属性的 getter 方法(若属性为 var 类型,还会生成 setter 方法)

  • equals() 方法(用于对象相等性判断)

  • hashCode() 方法(用于哈希值计算,支持集合中的快速查找)

  • toString() 方法(返回属性信息的字符串表示,便于调试)

  • copy() 方法(用于复制对象并修改部分属性)

  • component1()、component2()...... 等组件函数(支持解构赋值,见"数据类"相关内容)

补充代码示例

kotlin 复制代码
// 1. 创建对象
val customer1 = Customer("张三", "zhangsan@example.com")
// 2. 调用 toString()
println(customer1) // 输出:Customer(name=张三, email=zhangsan@example.com)
// 3. 解构赋值(使用 component 函数)
val (name, email) = customer1
println("姓名:$name,邮箱:$email") // 输出:姓名:张三,邮箱:zhangsan@example.com
// 4. 复制对象并修改属性
val customer2 = customer1.copy(email = "zhangsan_new@example.com")
println(customer2) // 输出:Customer(name=张三, email=zhangsan_new@example.com)

重点记忆

data 关键字是核心,自动生成 6 大常用方法,避免重复编码;解构赋值和 copy() 是数据类最常用的便捷特性。

2.函数参数默认值

kotlin 复制代码
fun foo(a: Int = 0, b: String = "") { 
    println("a: $a, b: $b")
}

补充代码示例

kotlin 复制代码
// 1. 不传递任何参数,使用默认值
foo() // 输出:a: 0, b: 
// 2. 传递部分参数
foo(10) // 输出:a: 10, b: 
// 3. 传递指定参数(可打乱顺序)
foo(b = "hello", a = 20) // 输出:a: 20, b: hello

重点记忆

参数后加"= 默认值"即可设置默认值;调用时可指定参数名传递,灵活适配不同传参场景。

3.过滤列表

kotlin 复制代码
val positives = list.filter { x -> x > 0 }
// 更简洁的写法:
val positives = list.filter { it > 0 }

补充代码示例

kotlin 复制代码
val numbers = listOf(-3, -2, 0, 1, 2, 3)
// 过滤正整数
val positives = numbers.filter { it > 0 }
println(positives) // 输出:[1, 2, 3]
// 过滤非负数并转换为字符串
val nonNegativeStr = numbers.filter { it >= 0 }.map { it.toString() }
println(nonNegativeStr) // 输出:[0, 1, 2, 3]

重点记忆

filter 接收 lambda 表达式作为条件;当 lambda 只有一个参数时,可用 it 代替参数名简化代码。

了解 Java 与 Kotlin 过滤列表的区别。

4.检查集合中是否存在某元素

kotlin 复制代码
if ("john@example.com" in emailsList) { 
    println("约翰的邮箱存在")
}

if ("jane@example.com" !in emailsList) { 
    println("简的邮箱不存在")
}

补充代码示例

kotlin 复制代码
val fruits = listOf("苹果", "香蕉", "橙子")
val target = "香蕉"
if (target in fruits) {
    println("集合中包含 $target") // 输出:集合中包含 香蕉
} else {
    println("集合中不包含 $target")
}
// 结合 when 使用
val fruit = "葡萄"
when (fruit) {
    in fruits -> println("$fruit 是常见水果")
    else -> println("$fruit 不是常见水果") // 输出:葡萄 不是常见水果
}

重点记忆

用 in 表示"存在于",!in 表示"不存在于",语法直观,替代 Java 中的 contains() 方法。

5.字符串插值

kotlin 复制代码
println("Name $name")

补充代码示例

kotlin 复制代码
val name = "李四"
val age = 30
// 直接插入变量
println("姓名:$name,年龄:$age") // 输出:姓名:李四,年龄:30
// 插入表达式
println("明年年龄:${age + 1}") // 输出:明年年龄:31
// 插入函数调用结果
fun getGender() = "男"
println("性别:${getGender()}") // 输出:性别:男
// 插入对象属性
val customer = Customer("王五", "wangwu@example.com")
println("客户邮箱:${customer.email}") // 输出:客户邮箱:wangwu@example.com

重点记忆

用 <math xmlns="http://www.w3.org/1998/Math/MathML"> 符号引用变量,复杂表达式用 符号引用变量,复杂表达式用 </math>符号引用变量,复杂表达式用{} 包裹;替代 Java 中繁琐的 + 拼接或 String.format()。

了解 Java 与 Kotlin 字符串拼接的区别。

6.安全读取标准输入

kotlin 复制代码
// 读取字符串,若无法转换为整数则返回 null(例如输入"你好!")
val wrongInt = readln().toIntOrNull()
println(wrongInt)
// 输出:null

// 读取可转换为整数的字符串并返回整数(例如输入"13")
val correctInt = readln().toIntOrNull()
println(correctInt)
// 输出:13

补充代码示例

kotlin 复制代码
println("请输入一个整数:")
val input = readln().toIntOrNull()
// 结合空安全处理
val number = input ?: run {
    println("输入无效,使用默认值 0")
    0
}
println("最终数值:$number")
// 测试1:输入 25 → 输出:最终数值:25
// 测试2:输入 abc → 输出:输入无效,使用默认值 0;最终数值:0

重点记忆

使用 toIntOrNull() 等 *OrNull() 系列方法,避免转换失败抛出异常,返回 null 更安全。

更多信息请参考"读取标准输入"相关内容。

7.类型检查

kotlin 复制代码
when (x) {
    is Foo -> ... // x 是 Foo 类型时执行
    is Bar -> ... // x 是 Bar 类型时执行
    else   -> ... // 其他类型时执行
}

补充代码示例

kotlin 复制代码
open class Animal
class Dog : Animal() {
    fun bark() = println("汪汪叫")
}
class Cat : Animal() {
    fun meow() = println("喵喵叫")
}

fun animalSound(animal: Animal) {
    when (animal) {
        is Dog -> animal.bark() // 自动类型转换,可直接调用 Dog 方法
        is Cat -> animal.meow() // 自动类型转换
        else -> println("未知动物叫声")
    }
}

val dog = Dog()
val cat = Cat()
animalSound(dog) // 输出:汪汪叫
animalSound(cat) // 输出:喵喵叫

重点记忆

用 is 进行类型判断,判断后自动进行类型转换(智能转换),无需手动强转。

8.只读列表

kotlin 复制代码
val list = listOf("a", "b", "c")

补充代码示例

kotlin 复制代码
// 创建空只读列表
val emptyList = listOf<String>()
println(emptyList.isEmpty()) // 输出:true
// 创建包含多种类型元素的只读列表(不推荐,建议统一类型)
val mixedList = listOf("苹果", 10, true)
println(mixedList[0]) // 输出:苹果
// 只读列表不可修改,以下代码会编译报错
// list.add("d") 
// list[0] = "x"
// 若需修改,可转换为可变列表
val mutableList = list.toMutableList()
mutableList.add("d")
println(mutableList) // 输出:[a, b, c, d]

重点记忆

用 listOf() 创建只读列表,不支持 add、remove 等修改操作;如需修改,转换为 mutableListOf() 实现。

9.只读映射

kotlin 复制代码
val map = mapOf("a" to 1, "b" to 2, "c" to 3)

补充代码示例

kotlin 复制代码
// 创建空只读映射
val emptyMap = mapOf<String, Int>()
// 创建包含多个键值对的映射
val userMap = mapOf("name" to "赵六", "age" to 25, "gender" to "男")
// 读取值
println("姓名:${userMap["name"]}") // 输出:姓名:赵六
// 读取不存在的键,返回 null
println("address:${userMap["address"]}") // 输出:address:null
// 结合 getOrElse 处理不存在的键
val address = userMap.getOrElse("address") { "未知地址" }
println("地址:$address") // 输出:地址:未知地址
// 只读映射不可修改,以下代码编译报错
// userMap["age"] = 26
// userMap.put("address", "北京")

重点记忆

用 mapOf() 创建只读映射,键值对用"键 to 值"表示;读取不存在的键返回 null,而非抛出异常。

10.访问映射条目

kotlin 复制代码
println(map["key"])
map["key"] = value // 仅可变映射支持

补充代码示例

kotlin 复制代码
// 只读映射访问
val readOnlyMap = mapOf("one" to 1, "two" to 2)
println(readOnlyMap["one"]) // 输出:1
// 可变映射访问与修改
val mutableMap = mutableMapOf("one" to 1, "two" to 2)
// 修改已有键的值
mutableMap["one"] = 10
// 添加新键值对
mutableMap["three"] = 3
println(mutableMap) // 输出:{one=10, two=2, three=3}
// 用 getValue 读取,不存在则抛出异常
try {
    println(mutableMap.getValue("four"))
} catch (e: NoSuchElementException) {
    println("键 four 不存在") // 输出:键 four 不存在
}

重点记忆

只读映射仅支持读取([] 运算符),可变映射(mutableMapOf())支持读写([] 赋值);getValue() 不存在时抛异常。

11.遍历映射或键值对列表

kotlin 复制代码
for ((k, v) in map) {
    println("$k -> $v")
}

k 和 v 可以是任意便捷的名称,例如 name 和 age。

补充代码示例

kotlin 复制代码
val productMap = mapOf("手机" to 5999, "电脑" to 8999, "平板" to 2999)
// 遍历映射的键值对
for ((product, price) in productMap) {
    println("$product 的价格:$price 元")
}
// 输出:
// 手机 的价格:5999 元
// 电脑 的价格:8999 元
// 平板 的价格:2999 元

// 遍历键值对列表
val pairList = listOf("苹果" to "红", "香蕉" to "黄", "橙子" to "橙")
for ((fruit, color) in pairList) {
    println("$fruit 是 $color 色的")
}
// 输出:
// 苹果 是 红色的
// 香蕉 是 黄色的
// 橙子 是 橙色的

重点记忆

用 (k, v) 解构键值对进行遍历,变量名可自定义,比 Java 遍历 entrySet() 更简洁。

12.遍历区间

kotlin 复制代码
for (i in 1..100) { ... }  // 闭区间:包含 100
for (i in 1..<100) { ... } // 开区间:不包含 100
for (x in 2..10 step 2) { ... } // 步长为 2
for (x in 10 downTo 1) { ... } // 倒序遍历
(1..10).forEach { ... } // 结合 forEach 遍历

补充代码示例

kotlin 复制代码
// 1. 闭区间遍历(1 到 5,包含 5)
print("闭区间 1..5:")
for (i in 1..5) {
    print("$i ") // 输出:闭区间 1..5:1 2 3 4 5 
}
println()

// 2. 开区间遍历(1 到 5,不包含 5)
print("开区间 1..<5:")
for (i in 1..<5) {
    print("$i ") // 输出:开区间 1..<5:1 2 3 4 
}
println()

// 3. 步长遍历(2 到 10,每次加 2)
print("步长 2 遍历 2..10:")
for (x in 2..10 step 2) {
    print("$x ") // 输出:步长 2 遍历 2..10:2 4 6 8 10 
}
println()

// 4. 倒序遍历(10 到 1)
print("倒序遍历 10 downTo 1:")
for (x in 10 downTo 1 step 3) {
    print("$x ") // 输出:倒序遍历 10 downTo 1:10 7 4 1 
}
println()

// 5. 结合 forEach
print("forEach 遍历 1..3:")
(1..3).forEach { print("$it ") } // 输出:forEach 遍历 1..3:1 2 3 
println()

重点记忆

.. 表示闭区间,..< 表示开区间;step 设步长,downTo 倒序;区间遍历语法直观,替代 Java 中的 for (int i=...; ...; ...)。

13.延迟初始化属性

kotlin 复制代码
val p: String by lazy { // 仅在第一次访问时计算值
    // 计算字符串的逻辑
    "延迟初始化的值"
}

补充代码示例

kotlin 复制代码
// 模拟耗时计算
fun fetchData(): String {
    println("开始获取数据(耗时操作)")
    Thread.sleep(1000) // 模拟耗时
    return "从服务器获取的用户数据"
}

// 延迟初始化属性
val userData: String by lazy {
    fetchData() // 第一次访问时才执行
}

println("程序启动")
// 第一次访问,触发 lazy 中的逻辑
println("第一次获取数据:$userData")
// 输出:
// 程序启动
// 开始获取数据(耗时操作)
// 第一次获取数据:从服务器获取的用户数据

// 第二次访问,直接使用缓存的值
println("第二次获取数据:$userData")
// 输出:第二次获取数据:从服务器获取的用户数据

重点记忆

用 by lazy 修饰 val 属性,首次访问时执行 lambda 计算值并缓存,后续访问直接用缓存值,适合耗时初始化场景。

14.扩展函数

kotlin 复制代码
fun String.spaceToCamelCase() { 
    // 将空格分隔的字符串转为驼峰式
    return this.split(" ").joinToString("") { it.capitalize() }
}

"Convert this to camelcase".spaceToCamelCase()

补充代码示例

kotlin 复制代码
// 为 String 扩展反转字符串函数
fun String.reverseString(): String {
    return this.reversed()
}

val str = "hello"
println(str.reverseString()) // 输出:olleh

// 为 Int 扩展判断是否为偶数的函数
fun Int.isEven(): Boolean {
    return this % 2 == 0
}

val num1 = 4
val num2 = 5
println("$num1 是偶数吗?${num1.isEven()}") // 输出:4 是偶数吗?true
println("$num2 是偶数吗?${num2.isEven()}") // 输出:5 是偶数吗?false

// 为 List<Int> 扩展求和函数
fun List<Int>.sumAll(): Int {
    var total = 0
    this.forEach { total += it }
    return total
}

val numbers = listOf(1, 2, 3, 4)
println("列表求和:${numbers.sumAll()}") // 输出:列表求和:10

重点记忆

语法:fun 目标类型.函数名(参数) { ... };无需继承即可为现有类扩展功能,避免工具类冗余。

15.创建单例

kotlin 复制代码
object Resource {
    val name = "Name"
    fun getResourceInfo() = "资源名称:$name"
}

补充代码示例

kotlin 复制代码
// 单例对象:应用配置
object AppConfig {
    val appName = "Kotlin 应用"
    val version = "1.0.0"
    fun getConfigInfo(): String {
        return "应用名称:$appName,版本:$version"
    }
}

// 直接通过对象名访问,无需创建实例
println(AppConfig.appName) // 输出:Kotlin 应用
println(AppConfig.getConfigInfo()) // 输出:应用名称:Kotlin 应用,版本:1.0.0

// 单例中可包含静态常量和方法(替代 Java 中的 static)
object MathUtils {
    const val PI = 3.1415926
    fun circleArea(radius: Double): Double {
        return PI * radius * radius
    }
}

println("圆面积(半径 2):${MathUtils.circleArea(2.0)}") // 输出:圆面积(半径 2):12.5663704

重点记忆

用 object 关键字定义单例,全局唯一实例,直接通过对象名访问;替代 Java 中的饿汉式单例或枚举单例。

16.使用内联值类实现类型安全

kotlin 复制代码
@JvmInline
value class EmployeeId(private val id: String)

@JvmInline
value class CustomerId(private val id: String)

若不小心混淆了 EmployeeId 和 CustomerId,会触发编译错误。

仅在 JVM 后端中需要 @JvmInline 注解。

补充代码示例

kotlin 复制代码
// 内联值类:用户 ID 和订单 ID
@JvmInline
value class UserId(private val id: Long)

@JvmInline
value class OrderId(private val id: Long)

// 函数:根据用户 ID 查询订单
fun queryOrders(userId: UserId) {
    println("查询用户 ${userId} 的订单")
}

// 正确使用
val userId = UserId(1001)
queryOrders(userId) // 输出:查询用户 UserId(1001) 的订单

// 错误使用:传递 OrderId 会编译报错
val orderId = OrderId(2001)
// queryOrders(orderId) // 编译错误:Type mismatch: inferred type is OrderId but UserId was expected

// 为内联值类扩展函数
fun UserId.getUserIdStr(): String {
    return "U${this.toString().replace("UserId(", "").replace(")", "")}"
}

println(userId.getUserIdStr()) // 输出:U1001

重点记忆

用 value class 定义,包装基本类型;编译时检查类型,避免同类型值混淆(如 ID 类型),且性能接近基本类型。

17.实例化抽象类

kotlin 复制代码
abstract class MyAbstractClass {
    abstract fun doSomething()
    abstract fun sleep()
}

fun main() {
    val myObject = object : MyAbstractClass() {
        override fun doSomething() {
            println("执行 doSomething")
        }

        override fun sleep() {
            println("执行 sleep")
        }
    }
    myObject.doSomething() // 输出:执行 doSomething
    myObject.sleep() // 输出:执行 sleep
}

补充代码示例

kotlin 复制代码
// 抽象类:形状
abstract class Shape {
    abstract fun calculateArea(): Double
    abstract fun calculatePerimeter(): Double
}

fun main() {
    // 匿名对象实例化抽象类(创建临时矩形实例)
    val rectangle = object : Shape() {
        private val length = 4.0
        private val width = 5.0

        override fun calculateArea(): Double {
            return length * width
        }

        override fun calculatePerimeter(): Double {
            return 2 * (length + width)
        }
    }

    println("矩形面积:${rectangle.calculateArea()}") // 输出:矩形面积:20.0
    println("矩形周长:${rectangle.calculatePerimeter()}") // 输出:矩形周长:18.0

    // 作为参数传递
    fun printShapeInfo(shape: Shape) {
        println("面积:${shape.calculateArea()},周长:${shape.calculatePerimeter()}")
    }
    printShapeInfo(rectangle) // 输出:面积:20.0,周长:18.0
}

重点记忆

用 object : 抽象类() { 重写抽象方法 } 创建匿名对象实例化抽象类;适合临时使用抽象类实例的场景,无需定义具体子类。

18.非空缩写(If-not-null shorthand)

kotlin 复制代码
val files = File("Test").listFiles()

println(files?.size) // 若 files 非空则打印大小

补充代码示例

kotlin 复制代码
data class User(val name: String, val address: Address?)
data class Address(val city: String, val street: String?)

// 创建用户,address 可能为 null
val user1 = User("张三", Address("北京", "中关村大街"))
val user2 = User("李四", null)

// 访问可能为 null 的属性,用 ?. 避免空指针
println("user1 城市:${user1.address?.city}") // 输出:user1 城市:北京
println("user2 城市:${user2.address?.city}") // 输出:user2 城市:null

// 链式调用
println("user1 街道:${user1.address?.street}") // 输出:user1 街道:中关村大街
// 若 address 为 null,后续调用不执行,直接返回 null
println("user2 街道:${user2.address?.street}") // 输出:user2 街道:null

重点记忆

用 ?. 访问可能为 null 的属性或方法,若对象为 null 则整个表达式返回 null,避免空指针异常(NPE)。

19.非空否则缩写(If-not-null-else shorthand)

kotlin 复制代码
val files = File("Test").listFiles()

// 简单默认值场景:
println(files?.size ?: "empty") // 若 files 为 null,打印 "empty"

// 复杂默认值场景(用 run 代码块):
val filesSize = files?.size ?: run {
    val someSize = getSomeSize()
    someSize * 2
}
println(filesSize)

补充代码示例

kotlin 复制代码
// 简单默认值
val name: String? = null
val displayName = name ?: "匿名用户"
println(displayName) // 输出:匿名用户

// 结合函数调用
fun getDefaultAge() = 18
val age: Int? = null
val displayAge = age ?: getDefaultAge()
println(displayAge) // 输出:18

// 复杂默认值(run 代码块)
fun calculateDefaultScore(): Int {
    println("计算默认分数(复杂逻辑)")
    return 60
}

val score: Int? = null
val displayScore = score ?: run {
    println("分数为 null,使用默认计算逻辑")
    calculateDefaultScore()
}
println("最终分数:$displayScore")
// 输出:
// 分数为 null,使用默认计算逻辑
// 计算默认分数(复杂逻辑)
// 最终分数:60

重点记忆

?: 运算符表示"若左侧非空则用左侧,否则用右侧";复杂默认值用 run 代码块包裹,延迟执行。

21.为 null 时执行表达式(Execute an expression if null)

kotlin 复制代码
val values = mapOf("name" to "张三")
val email = values["email"] ?: throw IllegalStateException("Email is missing!")

补充代码示例

kotlin 复制代码
// 1. 基础用法:必要值缺失抛异常
val values = mapOf("name" to "张三")
// 邮箱为必要参数,缺失则抛异常
val email = values["email"] ?: throw IllegalStateException("Email is missing!")

// 2. 官方推荐:结合run执行多语句
val userName = values["username"] ?: run {
    println("用户名缺失,使用默认用户名")
    "default_user" // 多语句场景返回默认值
}
println("当前用户:$userName") // 输出:用户名缺失,使用默认用户名;当前用户:default_user

// 3. 结合对象属性使用
data class User(val name: String?, val phone: String?)
val user = User("李四", null)
// 手机号缺失时执行提示并返回默认值
val userPhone = user.phone ?: run {
    println("用户${user.name}未绑定手机号")
    "未知号码"
}
println(userPhone) // 输出:用户李四未绑定手机号;未知号码

// 4. 用TODO()标记未完善的异常处理逻辑
fun getRequiredParam(params: Map<String, String>, key: String): String {
    return params[key] ?: run {
        // TODO("待完善:记录缺失参数的日志,便于问题排查")
        throw IllegalArgumentException("参数 $key 不能为空")
    }
}

重点记忆

  1. 核心用法:结合 ?: 与 throw 实现"必要值缺失快速抛异常",替代冗长的 if (null) throw 逻辑;
  2. 多语句场景:用 ?: run { ... } 包裹复杂逻辑,代码块最后一行作为返回值;
  3. 未完成标记:用 TODO() 函数标记待完善逻辑,IDE会高亮提示未完成。

结合 ?: 与 throw 实现"必要值缺失时快速抛异常",替代冗长的 if (null) throw 逻辑,代码更简洁。

kotlin 复制代码
// 从映射中获取必要参数,不存在则抛异常
val userParams = mapOf("username" to "zhangsan", "password" to "123456")
// 必要参数:username 和 password
val username = userParams["username"] ?: throw IllegalArgumentException("用户名不能为空")
val password = userParams["password"] ?: throw IllegalArgumentException("密码不能为空")
println("用户名:$username,密码:$password") // 输出:用户名:zhangsan,密码:123456

// 从对象中获取必要属性
data class Product(val id: String?, val name: String?)
val product = Product(null, "手机")
val productId = product.id ?: throw IllegalStateException("产品 ID 不能为空")
// 执行到此处会抛异常:IllegalStateException: 产品 ID 不能为空
kotlin 复制代码
// 从映射中获取必要参数,不存在则抛异常
val userParams = mapOf("username" to "zhangsan", "password" to "123456")
// 必要参数:username 和 password
val username = userParams["username"] ?: throw IllegalArgumentException("用户名不能为空")
val password = userParams["password"] ?: throw IllegalArgumentException("密码不能为空")
println("用户名:$username,密码:$password") // 输出:用户名:zhangsan,密码:123456

// 从对象中获取必要属性
data class Product(val id: String?, val name: String?)
val product = Product(null, "手机")
val productId = product.id ?: throw IllegalStateException("产品 ID 不能为空")
// 执行到此处会抛异常:IllegalStateException: 产品 ID 不能为空

22.获取可能为空的集合的第一个元素

kotlin 复制代码
val emails = ... // 可能为空的集合
val mainEmail = emails.firstOrNull() ?: ""

了解 Java 与 Kotlin 获取第一个元素的区别。

补充代码示例

kotlin 复制代码
// 1. 非空集合获取第一个元素
val fruits = listOf("苹果", "香蕉", "橙子")
val firstFruit = fruits.firstOrNull() ?: "无水果"
println(firstFruit) // 输出:苹果

// 2. 空集合获取第一个元素(返回默认值)
val emptyFruits = emptyList<String>()
val firstEmptyFruit = emptyFruits.firstOrNull() ?: "无水果"
println(firstEmptyFruit) // 输出:无水果

// 3. 带条件获取第一个元素,无匹配则返回默认值
val numbers = listOf(1, 2, 3, 4, 5)
// 获取第一个大于 3 的元素,无则返回 0
val firstGreaterThan3 = numbers.firstOrNull { it > 3 } ?: 0
println(firstGreaterThan3) // 输出:4

// 4. 对比 first() 方法(无匹配时抛异常)
try {
    val firstLessThan0 = numbers.first { it < 0 }
} catch (e: NoSuchElementException) {
    println("无小于 0 的元素") // 输出:无小于 0 的元素
}

重点记忆

firstOrNull() 为空或无匹配元素时返回 null,结合 ?: 设默认值;first() 无匹配时抛异常,需谨慎使用。

23.非空时执行代码(Execute if not null)

kotlin 复制代码
val value = ...

value?.let {
    ... // 非空时执行此代码块
}

补充代码示例

kotlin 复制代码
// 1. 非空时执行打印
val message: String? = "Hello Kotlin"
message?.let {
    println("消息内容:$it") // 输出:消息内容:Hello Kotlin
}

// 2. 空时不执行
val nullMessage: String? = null
nullMessage?.let {
    println("空消息不会执行此代码") // 无输出
}

// 3. 结合链式调用处理非空数据
data class User(val name: String?, val age: Int?)
val user = User("张三", 30)
user?.name?.let { userName ->
    user.age?.let { userAge ->
        println("用户名:$userName,年龄:$userAge") // 输出:用户名:张三,年龄:30
    }
}

// 4. 非空时作为参数传递
fun printLength(str: String) {
    println("字符串长度:${str.length}")
}
val testStr: String? = "测试字符串"
testStr?.let { printLength(it) } // 输出:字符串长度:5

重点记忆

value?.let { ... } 表示"若 value 非空,则将其作为 it 传入代码块执行";避免嵌套 if (value != null) 逻辑。

24.非空时映射可空值(Map nullable value if not null)

kotlin 复制代码
val value = ...

val mapped = value?.let { transformValue(it) } ?: defaultValue
// 若 value 为 null 或转换结果为 null,返回 defaultValue

补充代码示例

kotlin 复制代码
// 1. 非空时转换,空时用默认值
fun transformNumber(num: Int): Int {
    return num * 2
}

val num1: Int? = 5
val mapped1 = num1?.let { transformNumber(it) } ?: 0
println(mapped1) // 输出:10(5*2)

val num2: Int? = null
val mapped2 = num2?.let { transformNumber(it) } ?: 0
println(mapped2) // 输出:0(默认值)

// 2. 转换结果可能为 null 时的处理
fun parseStringToInt(str: String): Int? {
    return str.toIntOrNull()
}

val str1: String? = "10"
val result1 = str1?.let { parseStringToInt(it) } ?: -1
println(result1) // 输出:10(转换成功)

val str2: String? = "abc"
val result2 = str2?.let { parseStringToInt(it) } ?: -1
println(result2) // 输出:-1(转换结果为 null,用默认值)

val str3: String? = null
val result3 = str3?.let { parseStringToInt(it) } ?: -1
println(result3) // 输出:-1(原值为 null,用默认值)

重点记忆

value?.let { 转换逻辑 } ?: 默认值,覆盖"原值空"和"转换结果空"两种场景,实现安全转换+默认值兜底。

25.when 语句返回值(Return on when statement)

kotlin 复制代码
fun transform(color: String): Int {
    return when (color) {
        "Red" -> 0
        "Green" -> 1
        "Blue" -> 2
        else -> throw IllegalArgumentException("Invalid color param value")
    }
}

补充代码示例

kotlin 复制代码
// 1. 基础类型映射
fun getColorCode(color: String): Int {
    return when (color) {
        "红色" -> 0xFF0000
        "绿色" -> 0x00FF00
        "蓝色" -> 0x0000FF
        else -> throw IllegalArgumentException("不支持的颜色:$color")
    }
}

println(getColorCode("红色")) // 输出:16711680
// println(getColorCode("黄色")) // 抛异常:IllegalArgumentException: 不支持的颜色:黄色

// 2. 结合类型判断返回不同类型(需指定返回类型)
fun getTypeInfo(value: Any): String {
    return when (value) {
        is String -> "字符串类型,长度:${value.length}"
        is Int -> "整数类型,值:$value"
        is Boolean -> "布尔类型,值:$value"
        else -> "未知类型"
    }
}

println(getTypeInfo("test")) // 输出:字符串类型,长度:4
println(getTypeInfo(100)) // 输出:整数类型,值:100
println(getTypeInfo(true)) // 输出:布尔类型,值:true

// 3. 简化为单表达式函数
fun getWeekday(index: Int): String = when (index) {
    1 -> "周一"
    2 -> "周二"
    3 -> "周三"
    4 -> "周四"
    5 -> "周五"
    6 -> "周六"
    7 -> "周日"
    else -> "无效索引"
}

println(getWeekday(3)) // 输出:周三

重点记忆

when 可作为表达式返回值,需覆盖所有可能场景(else 分支);结合单表达式函数语法可大幅简化代码。

26.try-catch 表达式(try-catch expression)

kotlin 复制代码
fun test() {
    val result = try {
        count()
    } catch (e: ArithmeticException) {
        throw IllegalStateException(e)
    }

    // 处理 result
}

补充代码示例

kotlin 复制代码
// 1. 捕获异常并返回默认值
fun divide(a: Int, b: Int): Int {
    return try {
        a / b
    } catch (e: ArithmeticException) {
        println("除法异常:${e.message}")
        0 // 异常时返回默认值 0
    }
}

println(divide(10, 2)) // 输出:5
println(divide(10, 0)) // 输出:除法异常:/ by zero;0

// 2. 捕获异常并转换异常类型
fun parseInt(str: String): Int {
    return try {
        str.toInt()
    } catch (e: NumberFormatException) {
        throw IllegalArgumentException("无效的整数字符串:$str", e)
    }
}

try {
    parseInt("abc")
} catch (e: IllegalArgumentException) {
    println(e.message) // 输出:无效的整数字符串:abc
}

// 3. 结合 finally 块(finally 不影响返回值)
fun testFinally(): String {
    return try {
        println("执行 try 块")
        return "try 返回值"
    } catch (e: Exception) {
        "catch 返回值"
    } finally {
        println("执行 finally 块") // 无论是否异常都会执行
    }
}

println(testFinally())
// 输出:
// 执行 try 块
// 执行 finally 块
// try 返回值

重点记忆

try-catch 可作为表达式返回值,异常时执行 catch 分支;finally 块仅用于资源清理,不影响返回值。

17.if 表达式(if expression)

kotlin 复制代码
val y = if (x == 1) {
    "one"
} else if (x == 2) {
    "two"
} else {
    "other"
}

补充代码示例

kotlin 复制代码
// 1. 基础条件赋值
val x = 2
val y = if (x == 1) {
    "one"
} else if (x == 2) {
    "two"
} else {
    "other"
}
println(y) // 输出:two

// 2. 简化单行写法
val age = 18
val isAdult = if (age >= 18) true else false
println(isAdult) // 输出:true

// 3. 代码块中执行复杂逻辑后返回值
val score = 85
val grade = if (score >= 90) {
    println("成绩优秀")
    "A"
} else if (score >= 80) {
    println("成绩良好")
    "B"
} else if (score >= 60) {
    println("成绩及格")
    "C"
} else {
    println("成绩不及格")
    "D"
}
println("等级:$grade")
// 输出:
// 成绩良好
// 等级:B

// 4. 替代三元运算符
val a = 10
val b = 20
val max = if (a > b) a else b
println("最大值:$max") // 输出:最大值:20

重点记忆

Kotlin 无三元运算符,用 if-else 表达式替代;代码块中最后一行表达式即为返回值,无需 return。

18.返回 Unit 的方法的构建器风格用法(Builder-style usage of methods that return Unit)

kotlin 复制代码
fun arrayOfMinusOnes(size: Int): IntArray {
    return IntArray(size).apply { fill(-1) }
}

补充代码示例

kotlin 复制代码
// 1. 数组初始化并填充值
fun arrayOfZeros(size: Int): IntArray {
    // 创建数组后立即调用 fill 方法填充 0
    return IntArray(size).apply { fill(0) }
}

val zeroArray = arrayOfZeros(5)
println(zeroArray.contentToString()) // 输出:[0, 0, 0, 0, 0]

// 2. 集合初始化并添加元素
fun createFruitList(): List<String> {
    return mutableListOf<String>().apply {
        add("苹果")
        add("香蕉")
        add("橙子")
        sort() // 排序
    }
}

val fruitList = createFruitList()
println(fruitList) // 输出:[苹果, 橙子, 香蕉](中文按拼音排序)

// 3. 对象初始化并调用多个无返回值方法
class Printer {
    fun setColor(color: String) {
        println("设置颜色为:$color")
    }
    fun setSize(size: Int) {
        println("设置大小为:$size")
    }
    fun printContent(content: String) {
        println("打印内容:$content")
    }
}

fun createPrinter(): Printer {
    return Printer().apply {
        setColor("黑色")
        setSize(10)
        // 可链式调用多个无返回值方法
    }
}

val printer = createPrinter()
printer.printContent("Kotlin 教程")
// 输出:
// 设置颜色为:黑色
// 设置大小为:10
// 打印内容:Kotlin 教程

重点记忆

用 apply 方法实现构建器风格:创建对象后立即调用多个无返回值方法,最后返回对象本身,代码更连贯。

19.单表达式函数(Single-expression functions)

kotlin 复制代码
fun theAnswer() = 42

等价于

kotlin 复制代码
fun theAnswer(): Int {
    return 42
}

单表达式函数可与其他惯用语法有效结合,使代码更简洁。例如结合 when 表达式:

kotlin 复制代码
fun transform(color: String): Int = when (color) {
    "Red" -> 0
    "Green" -> 1
    "Blue" -> 2
    else -> throw IllegalArgumentException("Invalid color param value")
}

补充代码示例

kotlin 复制代码
// 1. 简单返回值函数
fun add(a: Int, b: Int) = a + b
println(add(3, 5)) // 输出:8

// 2. 结合条件表达式
fun isPositive(num: Int) = num > 0
println(isPositive(10)) // 输出:true
println(isPositive(-5)) // 输出:false

// 3. 结合函数调用
fun getGreeting(name: String) = "Hello, $name!"
println(getGreeting("张三")) // 输出:Hello, 张三!

// 4. 结合 when 表达式处理多分支
fun getSeason(month: Int) = when (month) {
    3, 4, 5 -> "春季"
    6, 7, 8 -> "夏季"
    9, 10, 11 -> "秋季"
    12, 1, 2 -> "冬季"
    else -> "无效月份"
}

println(getSeason(4)) // 输出:春季
println(getSeason(10)) // 输出:秋季

// 5. 带返回值类型注解(复杂场景建议显式指定)
fun multiply(a: Double, b: Double): Double = a * b
println(multiply(2.5, 4.0)) // 输出:10.0

重点记忆

函数体仅一个表达式时用 = 替代大括号和 return;简单场景可省略返回值类型(编译器推导),复杂场景建议显式指定。

20.对对象实例调用多个方法(with)

kotlin 复制代码
class Turtle {
    fun penDown()
    fun penUp()
    fun turn(degrees: Double)
    fun forward(pixels: Double)
}

val myTurtle = Turtle()
with(myTurtle) { // 绘制一个 100 像素的正方形
    penDown()
    for (i in 1..4) {
        forward(100.0)
        turn(90.0)
    }
    penUp()
}

补充代码示例

kotlin 复制代码
// 1. 对字符串调用多个方法
val str = "  Kotlin  Tutorial  "
val processedStr = with(str) {
    trim() // 去除前后空格
    .lowercase() // 转为小写
    .replace("tutorial", "教程") // 替换内容
}
println(processedStr) // 输出:kotlin 教程

// 2. 对集合调用多个方法
val numbers = listOf(3, 1, 4, 1, 5, 9)
val result = with(numbers) {
    sorted() // 排序
    .distinct() // 去重
    .take(3) // 取前 3 个元素
}
println(result) // 输出:[1, 3, 4]

// 3. 自定义类对象调用多个方法
class Student {
    var name = ""
    var age = 0
    var grade = ""
    fun study() = println("$name 正在学习")
    fun exam() = println("$name 正在考试")
}

val student = Student()
with(student) {
    name = "李四"
    age = 18
    grade = "高三"
    study()
    exam()
}
// 输出:
// 李四 正在学习
// 李四 正在考试

// 4. with 返回代码块最后一个表达式的值
val studentInfo = with(student) {
    "姓名:$name,年龄:$age,年级:$grade"
}
println(studentInfo) // 输出:姓名:李四,年龄:18,年级:高三

重点记忆

with(对象) { ... } 中可直接调用对象方法/访问属性,无需重复写对象名;代码块最后一个表达式为返回值。

21.配置对象属性(apply)

kotlin 复制代码
val myRectangle = Rectangle().apply {
    length = 4
    breadth = 5
    color = 0xFAFAFA
}

这在配置对象构造函数中不存在的属性时非常有用。

补充代码示例

kotlin 复制代码
// 1. 配置数据类属性(无参构造需单独指定)
data class Person(var name: String = "", var age: Int = 0, var address: String = "")

val person = Person().apply {
    name = "王五"
    age = 25
    address = "北京市海淀区"
}
println(person) // 输出:Person(name=王五, age=25, address=北京市海淀区)

// 2. 配置集合属性
val mutableMap = mutableMapOf<String, Int>().apply {
    put("苹果", 10)
    put("香蕉", 20)
    put("橙子", 15)
    remove("香蕉") // 移除不需要的键值对
}
println(mutableMap) // 输出:{苹果=10, 橙子=15}

// 3. 配置自定义类属性(构造函数无对应参数)
class Car {
    // 构造函数未包含的属性
    var brand: String = ""
    var model: String = ""
    var year: Int = 0
    // 构造函数参数
    var price: Double = 0.0
}

val myCar = Car(price = 150000.0).apply {
    brand = "丰田"
    model = "凯美瑞"
    year = 2024
}
println("品牌:${myCar.brand},型号:${myCar.model},年份:${myCar.year},价格:${myCar.price}")
// 输出:品牌:丰田,型号:凯美瑞,年份:2024,价格:150000.0

// 4. 链式配置并返回对象
fun createConfiguredUser(): Person {
    return Person().apply {
        name = "赵六"
        age = 30
    }.apply {
        address = "上海市浦东新区" // 可链式调用多个 apply
    }
}

val configuredUser = createConfiguredUser()
println(configuredUser) // 输出:Person(name=赵六, age=30, address=上海市浦东新区)

重点记忆

apply 与 with 类似,但始终返回对象本身,支持链式调用;适合对象创建后集中配置属性,代码更简洁。

22.Java 7 的 try-with-resources

kotlin 复制代码
val stream = Files.newInputStream(Paths.get("/some/file.txt"))
stream.buffered().reader().use { reader ->
    println(reader.readText())
}

补充代码示例

kotlin 复制代码
// 1. 读取文件内容(自动关闭流,官方链式use风格)
import java.nio.file.Files
import java.nio.file.Paths

fun readFileContent(filePath: String): String {
    // 链式调用use,自动关闭所有实现AutoCloseable的资源
    return Files.newInputStream(Paths.get(filePath))
        .buffered()
        .reader()
        .use { it.readText() } // 简洁写法:it指代reader
}

// 测试(需确保文件存在,此处仅为示例)
// val content = readFileContent("test.txt")
// println(content)

// 2. 写入文件内容
fun writeFileContent(filePath: String, content: String) {
    Files.newBufferedWriter(Paths.get(filePath)).use { writer ->
        writer.write(content)
        writer.newLine()
        writer.write("这是第二行内容")
    }
}

// 测试
// writeFileContent("output.txt", "这是第一行内容")

// 3. 处理数据库连接(多层链式use,自动关闭资源)
import java.sql.Connection
import java.sql.DriverManager
import java.sql.ResultSet

fun queryUserCount(): Int {
    val url = "jdbc:mysql://localhost:3306/test"
    val user = "root"
    val password = "123456"

    // 连接、语句、结果集链式use,均会自动关闭
    Connection::class.java.forName("com.mysql.cj.jdbc.Driver")
    return DriverManager.getConnection(url, user, password)
        .createStatement()
        .executeQuery("SELECT COUNT(*) FROM user")
        .use { it.next(); it.getInt(1) }
}

// 4. 用TODO()标记未完善的资源处理逻辑
fun copyFile(sourcePath: String, targetPath: String) {
    Files.newInputStream(Paths.get(sourcePath)).use { input ->
        Files.newOutputStream(Paths.get(targetPath)).use { output ->
            // TODO("待完善:添加文件复制进度提示功能")
            input.transferTo(output)
        }
    }
}

// 测试
// println("用户数量:${queryUserCount()}")
// copyFile("source.txt", "target.txt")

重点记忆

Kotlin 用 use 函数替代 Java 的 try-with-resources;实现 AutoCloseable 接口的资源调用 use 后会自动关闭,无需手动处理。

23.需要泛型类型信息的泛型函数

kotlin 复制代码
//  public final class Gson {
//     ...
//     public <T> T fromJson(JsonElement json, Class<T> classOfT) throws JsonSyntaxException {
//     ...

inline fun <reified T: Any> Gson.fromJson(json: JsonElement): T = this.fromJson(json, T::class.java)

补充代码示例

kotlin 复制代码
// 1. 简化 Gson 反序列化(无需传递 Class 对象)
import com.google.gson.Gson
import com.google.gson.JsonParser

// 定义扩展函数
inline fun <reified T : Any> Gson.fromJson(jsonStr: String): T {
    val jsonElement = JsonParser.parseString(jsonStr)
    return this.fromJson(jsonElement, T::class.java)
}

// 测试
data class User(val name: String, val age: Int)
val gson = Gson()
val jsonStr = "{\"name\":\"张三\",\"age\":30}"
// 无需传递 User::class.java,编译器通过 reified 推导
val user = gson.fromJson<User>(jsonStr)
println(user) // 输出:User(name=张三, age=30)

// 2. 自定义泛型函数(需要类型信息)
inline fun <reified T> isInstanceOf(value: Any): Boolean {
    // reified 允许在函数内部获取 T 的类型信息
    return value is T
}

println(isInstanceOf<String>("test")) // 输出:true
println(isInstanceOf<Int>("test")) // 输出:false

// 3. 泛型集合转换(需要元素类型信息)
inline fun <reified T> List<*>.filterIsInstanceToList(): List<T> {
    val result = mutableListOf<T>()
    for (element in this) {
        if (element is T) {
            result.add(element)
        }
    }
    return result
}

val mixedList = listOf("a", 1, 2.0, "b", 3)
val stringList = mixedList.filterIsInstanceToList<String>()
val intList = mixedList.filterIsInstanceToList<Int>()
println(stringList) // 输出:[a, b]
println(intList) // 输出:[1, 2, 3]

重点记忆

用 inline + reified 修饰泛型参数,可在函数内部获取泛型类型信息(T::class.java);解决泛型擦除导致无法获取类型的问题。

24.交换两个变量(Swap two variables)

kotlin 复制代码
var a = 1
var b = 2
a = b.also { b = a }

补充代码示例

kotlin 复制代码
// 1. 基础类型变量交换(核心实现)
var a = 10
var b = 20
println("交换前:a=$a, b=$b") // 输出:交换前:a=10, b=20
// 核心语法:also函数先执行括号内赋值,再返回原始值
a = b.also { b = a }
println("交换后:a=$a, b=$b") // 输出:交换后:a=20, b=10

// 2. 引用类型变量交换(字符串、对象等)
var str1 = "Kotlin"
var str2 = "Java"
println("引用类型交换前:str1=$str1, str2=$str2") // 输出:str1=Kotlin, str2=Java
str1 = str2.also { str2 = str1 }
println("引用类型交换后:str1=$str1, str2=$str2") // 输出:str1=Java, str2=Kotlin

// 3. 集合中指定索引元素交换
val mutableList = mutableListOf(10, 20, 30, 40)
println("集合交换前:$mutableList") // 输出:[10, 20, 30, 40]
// 交换索引1和3位置的元素
mutableList[1] = mutableList[3].also { mutableList[3] = mutableList[1] }
println("集合交换后:$mutableList") // 输出:[10, 40, 30, 20]

// 4. 对比传统临时变量方式(效果一致,代码略繁琐)
var x = 5
var y = 8
println("传统方式交换前:x=$x, y=$y") // 输出:x=5, y=8
val temp = x
x = y
y = temp
println("传统方式交换后:x=$x, y=$y") // 输出:x=8, y=5

// 5. 错误示范:不可变变量(val)无法交换
// val c = 3
// val d = 4
// c = d.also { d = c } // 编译报错:Val cannot be reassigned

// 6. 用TODO()标记未完成的交换逻辑
fun swapNullable(a: Int?, b: Int?): Pair<Int?, Int?> {
    // TODO("待实现:处理a或b为null时的交换逻辑,避免空指针")
    return b to a
}

重点记忆

  1. 核心语法:a = b.also { b = a },利用also函数"先执行副作用(赋值)再返回接收者"的特性实现无临时变量交换;
  2. 适用范围:支持所有可重新赋值的变量(var修饰),包括基础类型和引用类型;
  3. 注意事项:不可用于val修饰的不可变变量,因无法重新赋值;
  4. 标记未完成代码:使用TODO()函数标记待完善逻辑,编译时会提示未完成。

25.标记代码为未完成(Mark code as incomplete (TODO))

Kotlin 标准库中有一个TODO()函数总是会抛出异常NotImplementedError。它的返回类型为 NoneNothing因此无论预期类型如何都可以使用。此外,还有一个重载版本,接受一个 reason 参数:

Kotlin 复制代码
fun calcTaxes(): BigDecimal = TODO("Waiting for feedback from accounting")

IntelliJ IDEA 的 kotlin 插件能够理解 TODO 工具窗口中的代码指针的语义TODO()并自动添加代码指针。

补充代码示例

kotlin 复制代码
// 1. 基础用法:无参数TODO(),编译通过但运行抛异常
fun calculateTotal(prices: List<Double>): Double {
    TODO() // IDE会高亮提示"未实现的函数"
}

// 2. 带提示信息的TODO(),说明待实现内容
fun formatDate(date: Date): String {
    TODO("待实现:按yyyy-MM-dd格式化,处理null和非法日期")
}

// 3. 在代码块中使用,标记分支未完善
fun processOrder(order: Order) {
    when (order.status) {
        OrderStatus.PAID -> shipOrder(order)
        OrderStatus.CANCELLED -> refundOrder(order)
        OrderStatus.PENDING -> TODO("待实现:待支付订单的超时提醒逻辑")
    }
}

重点记忆

kotlin 复制代码
// 1. 结合空安全使用TODO()
data class User(val id: Long, val name: String?)
fun getUserById(id: Long): User? {
    val user = userRepository.findById(id)
    return user ?: run {
        TODO("待实现:用户不存在时的日志记录和默认用户返回")
        null
    }
}

// 2. 接口实现中标记未完成方法
interface PaymentService {
    fun pay(amount: Double)
    fun refund(amount: Double)
}

class AlipayService : PaymentService {
    override fun pay(amount: Double) {
        // 已实现支付逻辑
        println("支付宝支付 $amount 元")
    }

    override fun refund(amount: Double) {
        TODO("待对接支付宝退款接口,处理退款失败场景")
    }
}

// 3. 测试用例中标记未完成场景
fun testOrderFlow() {
    // 已完成:测试支付成功流程
    val paidOrder = Order(1, OrderStatus.PAID)
    check(shipOrder(paidOrder) == true)

    // 未完成:测试支付超时流程
    val timeoutOrder = Order(2, OrderStatus.PENDING)
    TODO("待测试:超过30分钟未支付的订单自动取消逻辑")
}

// 4. 与其他惯用语法结合(如try-catch)
fun parseData(data: String): Data {
    return try {
        JsonParser.parseString(data).toData()
    } catch (e: JsonSyntaxException) {
        TODO("待实现:JSON解析异常的重试机制,当前直接抛异常")
        throw e
    }
}
  1. 核心特性:TODO()是Kotlin标准库函数,编译时不报错(支持临时调试),运行时抛出NotImplementedError,IDE会高亮提示未完成;
  2. 实用技巧:传字符串参数明确待实现细节,可在函数、代码块、接口、测试用例等多场景使用;
  3. 最佳实践:上线前需通过IDE全局搜索(TODO)清理所有未完成代码,避免线上抛异常;
  4. 关联用法:可与空安全、try-catch等语法结合,标记局部未完善逻辑。

26.Kotlin 常用惯用语法核心特点总结

Kotlin 惯用语法围绕简洁性、安全性、高效性三大核心,通过语法层面的优化减少样板代码、降低异常风险,同时提升开发效率与代码可读性,核心特点如下:

核心维度 关键语法 核心优势
简洁高效 data class、单表达式函数、字符串插值、默认参数、扩展函数 自动生成常用方法(如 equals、copy),简化变量拼接、函数定义与现有类功能扩展,减少冗余编码
空安全保障 ?.、?:、let、toIntOrNull 等 *OrNull () 方法 编译时检查空指针风险,通过安全调用、默认值兜底、非空执行等语法,彻底规避空指针异常
便捷集合操作 listOf/mapOf、filter/map、区间遍历、解构赋值 快速创建只读集合,支持链式过滤转换,遍历语法直观(闭区间 / 开区间 / 倒序),解构赋值简化数据获取
对象与资源管理 apply/with、use 函数、object 单例 集中配置对象属性、简化多方法调用,自动管理 AutoCloseable 资源(替代 try-with-resources),便捷实现单例
泛型与类型安全 inline reified、value class 解决泛型擦除问题,支持泛型类型信息获取;内联值类实现类型安全,避免同类型值混淆(如 ID 类型)
场景化语法 when 表达式、firstOrNull、交换变量、延迟初始化 覆盖多分支判断、集合元素安全获取、变量交换、耗时初始化等实际场景,兼顾可读性与性能

整体来看,Kotlin 惯用语法既贴合实际开发需求,又通过编译时检查(如类型安全、空安全)提升代码可靠性。例如,data class 省去手动编写 getter/setter、equals 等方法的麻烦,空安全语法无需繁琐的空判断,扩展函数避免工具类冗余,use 函数简化资源关闭流程。这些语法设计既减少了开发工作量,又降低了维护成本,同时保持代码简洁易懂,实现了 "写得少、错得少、跑得好" 的开发目标,成为兼顾效率与质量的主流编程语言选择。

相关推荐
低调小一4 小时前
Android Gradle 的 compileOptions 与 Kotlin jvmTarget 全面理解(含案例)
android·开发语言·kotlin
Frank_HarmonyOS1 天前
在 Android 中使用协程(Coroutine)
kotlin
用户69371750013841 天前
Kotlin官方文档-基础知识-基础语法(翻译官方文档+自我总结)
kotlin
zhangphil1 天前
Kotlin线程池newFixedThreadPoolContext与约束协程运行的线程数量limitedParallelism
kotlin
用户69371750013841 天前
Kotlin 全量关键字全面整理,并附上简洁示例,确保每一个关键字都清楚易懂。
kotlin
消失的旧时光-19432 天前
Android ble理解
java·kotlin
studyForMokey2 天前
【Android Activity】生命周期深入理解
android·kotlin
来来走走2 天前
kotlin学习 lambda编程
android·学习·kotlin
Huang兄2 天前
kotlin协程-基础概念篇
kotlin