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 函数简化资源关闭流程。这些语法设计既减少了开发工作量,又降低了维护成本,同时保持代码简洁易懂,实现了 "写得少、错得少、跑得好" 的开发目标,成为兼顾效率与质量的主流编程语言选择。

相关推荐
FunnySaltyFish7 小时前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
Kapaseker13 小时前
Compose 进阶—巧用 GraphicsLayer
android·kotlin
Kapaseker1 天前
实战 Compose 中的 IntrinsicSize
android·kotlin
A0微声z3 天前
Kotlin Multiplatform (KMP) 中使用 Protobuf
kotlin
alexhilton4 天前
使用FunctionGemma进行设备端函数调用
android·kotlin·android jetpack
lhDream4 天前
Kotlin 开发者必看!JetBrains 开源 LLM 框架 Koog 快速上手指南(含示例)
kotlin
RdoZam4 天前
Android-封装基类Activity\Fragment,从0到1记录
android·kotlin
Kapaseker5 天前
研究表明,开发者对Kotlin集合的了解不到 20%
android·kotlin
糖猫猫cc5 天前
Kite:两种方式实现动态表名
java·kotlin·orm·kite
如此风景5 天前
kotlin协程学习小计
android·kotlin