1. 高级特性
内存管理
// Kotlin 使用 JVM 的垃圾回收机制
class MemoryExample {
// 使用 lateinit 延迟初始化
lateinit var lateInitVar: String
fun initialize() {
lateInitVar = "Initialized"
}
// 使用 lazy 延迟初始化
val lazyValue: String by lazy {
println("Computed!")
"Hello"
}
}
val example = MemoryExample()
// println(example.lateInitVar) // 会抛出异常,因为还未初始化
example.initialize()
println(example.lateInitVar) // Initialized
println(example.lazyValue) // 第一次访问时计算并缓存
println(example.lazyValue) // 使用缓存的值
多线程
import kotlinx.coroutines.*
// 使用协程 (比线程更轻量级)
fun main() = runBlocking {
println("Main thread: ${Thread.currentThread().name}")
// 启动协程
val job = launch {
delay(1000L) // 非阻塞延迟
println("World from ${Thread.currentThread().name}")
}
println("Hello from ${Thread.currentThread().name}")
job.join() // 等待协程完成
// 并发执行
val result1 = async {
delay(500L)
"Result 1"
}
val result2 = async {
delay(1000L)
"Result 2"
}
println("${result1.await()} and ${result2.await()}")
}
扩展函数
// 为 String 类添加扩展函数
fun String.addExclamation() = "$this!"
println("Hello".addExclamation()) // Hello!
// 可空类型的扩展
fun String?.nullSafeToString(): String = this ?: "NULL"
val s: String? = null
println(s.nullSafeToString()) // NULL
函数式编程
val numbers = listOf(1, 2, 3, 4, 5)
// 高阶函数
val doubled = numbers.map { it * 2 }
println(doubled) // [2, 4, 6, 8, 10]
// 过滤
val evens = numbers.filter { it % 2 == 0 }
println(evens) // [2, 4]
// 折叠/归约
val sum = numbers.reduce { acc, i -> acc + i }
println(sum) // 15
// 排序
val sorted = numbers.sortedByDescending { it }
println(sorted) // [5, 4, 3, 2, 1]
委托属性
import kotlin.properties.Delegates
class Example {
// 惰性初始化
val lazyValue: String by lazy {
println("Computed!")
"Hello"
}
// 可观察属性
var observableValue: String by Delegates.observable("<no name>") {
prop, old, new ->
println("$old -> $new")
}
// 非空检查
var notNullValue: String by Delegates.notNull()
}
val example = Example()
println(example.lazyValue) // 第一次访问时计算
println(example.lazyValue) // 使用缓存的值
example.observableValue = "First" // <no name> -> First
example.observableValue = "Second" // First -> Second
// example.notNullValue // 会抛出异常,因为还未初始化
example.notNullValue = "Initialized"
println(example.notNullValue) // Initialized
##2. 其他实用特性
###空安全
```kotlin
var neverNull: String = "This can't be null"
// neverNull = null // 编译错误
var nullable: String? = "This can be null"
nullable = null // 可以
// 安全调用
println(nullable?.length) // null
// Elvis 操作符
val length = nullable?.length ?: 0
println(length) // 0
// 非空断言 (慎用)
// val forcedLength = nullable!!.length // 如果 nullable 为 null 会抛出异常
类型别名
kotlin
typealias Name = String
typealias NameList = List<Name>
typealias NameMapper = (Name) -> Name
fun greet(name: Name, mapper: NameMapper): Name {
return mapper(name)
}
val result = greet("Alice") { "Hello, $it!" }
println(result) // Hello, Alice!
作用域函数
data class Person(var name: String, var age: Int)
val person = Person("Alice", 25)
// let - 在对象上执行代码块并返回结果
val letResult = person.let {
it.age += 1
"Name is ${it.name}"
}
println(letResult) // Name is Alice
// run - 类似 let,但使用 this 而不是 it
val runResult = person.run {
age += 1
"Name is $name"
}
println(runResult) // Name is Alice
// with - 类似 run,但作为函数而不是扩展
val withResult = with(person) {
age += 1
"Name is $name"
}
println(withResult) // Name is Alice
// apply - 在对象上执行代码块并返回对象本身
val appliedPerson = person.apply {
age += 1
name = name.uppercase()
}
println(appliedPerson) // Person(name=ALICE, age=27)
// also - 类似 apply,但使用 it 而不是 this
val alsoPerson = person.also {
it.age += 1
println("Age is now ${it.age}")
}
println(alsoPerson) // Person(name=ALICE, age=28)
Result 类型
Result 是 Kotlin 标准库中的一个密封类,用于表示操作的成功或失败结果,通常用于函数式错误处理。
基本用法
fun divide(a: Int, b: Int): Result<Int> {
return if (b == 0) {
Result.failure(ArithmeticException("Division by zero"))
} else {
Result.success(a / b)
}
}
fun main() {
val result = divide(10, 2)
when {
result.isSuccess -> println("Success: ${result.getOrNull()}")
result.isFailure -> println("Error: ${result.exceptionOrNull()?.message}")
}
// 输出: Success: 5
val failedResult = divide(10, 0)
failedResult.onFailure {
println("Operation failed: ${it.message}")
}
// 输出: Operation failed: Division by zero
}
Result 的常用操作
fun main() {
val result: Result<Int> = runCatching {
"123".toInt()
}
// 获取值或默认值
println(result.getOrElse { -1 }) // 123
// 映射成功结果
val doubled = result.map { it * 2 }
println(doubled.getOrNull()) // 246
// 恢复失败情况
val recovered = result.recover {
if (it is NumberFormatException) 0 else throw it
}
println(recovered.getOrNull()) // 123
// 链式操作
val finalResult = runCatching { "abc".toInt() }
.recover { 0 }
.map { it * 3 }
println(finalResult.getOrNull()) // 0
}
runCatching 函数
Kotlin 提供了 runCatching 函数来方便地创建 Result 对象:
fun parseNumber(str: String): Result<Int> = runCatching {
str.toInt()
}
fun main() {
parseNumber("123")
.onSuccess { println("Parsed: $it") }
.onFailure { println("Failed to parse: ${it.message}") }
// 输出: Parsed: 123
parseNumber("abc")
.onSuccess { println("Parsed: $it") }
.onFailure { println("Failed to parse: ${it.message}") }
// 输出: Failed to parse: For input string: "abc"
}