设计哲学
Kotlin 是 JVM 上的务实语言:与 Java 100% 互操作,默认不可变、默认非空,用简洁语法减少样板代码。
Kotlin 编译成 JVM 字节码,可直接调用全部 Java 库;Android 官方自 2019 年起首选 Kotlin。老项目多为 Java,互操作让迁移逐步进行。
空安全
类型系统区分 String(非空)与 String?(可空)。编译器强制你处理 null,从根上消灭 NPE。
var name: String? = null
val len = name?.length // 安全调用,name 为 null 时返回 null
val display = name ?: "匿名" // 空合并
val forced = name!!.length // 强制解包,null 时抛 NPE(慎用)
fun greet(input: String?) {
val n = input ?: return // Elvis 提前返回
println("hello $n")
}与 Swift 的强制解包同理,!! 在 null 时直接崩溃,仅在能 100% 保证非空时使用。
数据类与密封类
data class 自动生成 equals/hashCode/toString/copy;sealed class 表达受限的类层次,配合 when 可穷尽匹配。
data class User(val id: Long, val name: String)
sealed class UiState {
data object Loading : UiState()
data class Success(val data: List) : UiState()
data class Error(val msg: String) : UiState()
}
fun render(state: UiState) = when(state) { // 穷尽,无需 else
is UiState.Loading -> showSpinner()
is UiState.Success -> showList(state.data)
is UiState.Error -> showError(state.msg)
} 扩展函数
无需继承即可给已有类"添加"方法,是 Kotlin 表达力的核心。Android 大量 API 通过扩展增强。
fun String.truncate(max: Int) =
if (length <= max) this else take(max) + "…"
"Hello World".truncate(5) // "Hello…"
// 扩展属性
val Context.screenWidth: Int
get() = resources.displayMetrics.widthPixels高阶函数与 lambda
函数可作为参数与返回值。lambda 尾部调用可写在括号外,是 Kotlin DSL(如 Compose、Gradle Kotlin DSL)的基础。
fun <T> List<T>.filterIndexed(pred: (Int, T) -> Boolean): List<T> = ...
list.filter { it > 0 } // 单参用 it
list.fold(0) { acc, x -> acc + x } // 多参显式命名作用域函数
let/run/with/apply/also 在对象上下文中执行代码块,区别在于"返回什么、用谁做 this/it"。
| 函数 | 上下文 | 返回 | 典型用途 |
|---|---|---|---|
let | it | lambda 结果 | 空安全检查、链式转换 |
apply | this | 对象自身 | 对象初始化配置 |
also | it | 对象自身 | 副作用(日志、校验) |
run | this | lambda 结果 | 对象上计算一个值 |
属性与懒加载
val 不可变、var 可变;by lazy 延时到首次访问才计算,适合昂贵初始化。
val heavy: Database by lazy {
Database.connect() // 首次访问时才执行
}
val name: String get() = "computed" // 自定义 getter常见陷阱
val 只保证引用不可变,若它指向可变对象(如 val list = mutableListOf()),列表内容仍可变。需要真正不可变用 listOf()。
对密封类 when 不要求 else(编译器知穷尽);对普通类型则必须 else 否则漏分支编译报错,这是类型安全的保障。