# Kotlin编程

> 当进行Kotlin开发、Android开发、性能优化或互操作性处理时，分析代码质量和最佳实践。

- Skill: `microwind/kotlin` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add microwind/kotlin`
- Raw SKILL.md: https://api.skillmd.com/api/skills/microwind/kotlin/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: microwind (https://skillmd.com/u/microwind)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/microwind/kotlin

---


# Kotlin编程技能

## 概述
Kotlin是JVM上的现代编程语言，融合了函数式编程和面向对象编程的优势，提供了更简洁、安全的语法。Kotlin与Java的互操作性使其成为现代Android开发和后端开发的首选。不当的使用可能导致代码混乱、性能问题、互操作性问题。

**核心原则**: 好的Kotlin代码应该简洁优雅、类型安全、null安全、性能良好。坏的Kotlin代码会过度函数式、性能损耗、互操作性差。

## 何时使用

**始终:**
- Kotlin项目代码审查
- Android应用开发
- 函数式编程应用
- 协程和结构化并发
- 互操作性审查
- 性能优化

**触发短语:**
- "Kotlin最佳实践"
- "协程使用规范"
- "扩展函数应用"
- "DSL设计"
- "Kotlin性能优化"
- "Java互操作性"

## Kotlin编程技能功能

### 基础特性
- 变量和常量声明
- 函数和Lambda
- 类和对象
- 接口和继承
- 数据类和密封类

### Null安全
- 可空类型和非空类型
- Elvis操作符
- 安全调用操作符
- 非空断言
- 函数契约

### 集合和序列
- List, Set, Map操作
- 不可变集合
- 序列和流处理
- 高阶函数链
- 集合扩展函数

### 函数式编程
- Lambda表达式
- 高阶函数
- 扩展函数
- 作用域函数（let, apply, run, with, also）
- 函数组合

### 协程和并发
- 协程基础和suspend
- launch和async
- 通道（Channel）
- 流（Flow）
- 结构化并发

### 面向对象特性
- 继承和实现
- 属性委托
- 对象表达式
- 方法重写
- super调用

## 常见问题

### Null安全问题
- **问题**: 不当使用非空断言
- **原因**: 草率使用!!操作符
- **解决**: 优先使用安全调用?、Elvis操作符?:或let块

- **问题**: 集合中可能包含null
- **原因**: 没有区分List<String>和List<String?>
- **解决**: 明确区分可空元素，避免混淆

### 性能问题
- **问题**: 过度使用扩展函数链
- **原因**: 每次链式调用都产生新的对象
- **解决**: 对大规模数据使用Sequence而不是Iterable

- **问题**: 协程滥用
- **原因**: 为简单操作创建过多协程
- **解决**: 合理评估协程的必要性

### 互操作性问题
- **问题**: Java调用Kotlin函数报空指针
- **原因**: Java没有理解Kotlin的非空注解
- **解决**: 使用@NotNull/@Nullable注解明确标注

## 代码示例

### Null安全
```kotlin
// 非空和可空类型
fun nullSafetyDemo(name: String?, age: Int?) {
    // 安全调用操作符
    val length = name?.length  // 如果name为null，返回null
    println(length)  // null或Int
    
    // Elvis操作符
    val safeName = name ?: "Unknown"
    val safeAge = age ?: 0
    println("$safeName is $safeAge years old")
    
    // let块（只在非null时执行）
    name?.let { validName ->
        println("Name is $validName")
    }
    
    // 多个null检查
    if (name != null && age != null && age > 0) {
        println("$name is $age years old")
    }
}

// 不可空和可空参数混合
fun processUser(name: String, email: String?) {
    email?.let { validEmail ->
        println("Email: $validEmail")
    } ?: run {
        println("No email provided")
    }
}

// 函数返回类型建议null可能性
fun findUserById(id: Int): User? {
    return if (id > 0) User(id, "John") else null
}
```

### 函数式编程和作用域函数
```kotlin
data class Person(val name: String, var age: Int, var email: String?)

fun functionProgrammingDemo() {
    val person = Person("Alice", 30, null)
    
    // apply - 初始化对象
    val result = person.apply {
        age = 31
        email = "alice@example.com"
    }
    
    // let - 转换
    val description = person.let {
        "Name: ${it.name}, Age: ${it.age}"
    }
    
    // run - 执行代码块并返回结果
    val ageGroup = person.run {
        when (age) {
            in 0..18 -> "Minor"
            in 19..65 -> "Adult"
            else -> "Senior"
        }
    }
    
    // with - 执行代码块，不返回
    with(person) {
        println("$name is $age years old")
        println("Email: $email")
    }
    
    // also - 执行代码块，返回原对象
    person.also { p ->
        println("Processing person: $p")
    }
}

// 集合操作
fun collectionOperationsDemo() {
    val numbers = listOf(1, 2, 3, 4, 5)
    
    // 链式操作
    val result = numbers
        .filter { it > 2 }
        .map { it * it }
        .fold(0) { acc, value -> acc + value }
    
    // 使用Sequence减少中间对象
    val largeList = (1..1000000).toList()
    val seqResult = largeList.asSequence()
        .filter { it % 2 == 0 }
        .map { it * 2 }
        .take(10)
        .toList()
    
    // 高阶函数
    val doubled = numbers.map { it * 2 }
    val adults = listOf(
        Person("Alice", 30, "alice@example.com"),
        Person("Bob", 25, "bob@example.com"),
        Person("Charlie", 17, null)
    ).filter { it.age >= 18 }
}
```

### 数据类和密封类
```kotlin
// 数据类 - 自动生成equals, hashCode, toString, copy
data class User(val id: Int, val name: String, val email: String)

// 密封类 - 限制继承
sealed class Result<out T> {
    data class Success<T>(val value: T) : Result<T>()
    data class Error(val exception: Exception) : Result<Nothing>()
    object Loading : Result<Nothing>()
}

fun handleResult(result: Result<String>) {
    when (result) {  // 穷举所有情况，编译器检查
        is Result.Success -> println("Value: ${result.value}")
        is Result.Error -> println("Error: ${result.exception.message}")
        is Result.Loading -> println("Loading...")
    }
}

// 使用示例
fun dataClassDemo() {
    val user1 = User(1, "Alice", "alice@example.com")
    val user2 = user1.copy(id = 2)  // 复制并修改
    
    println(user1 == user2)  // false (id不同)
    println(user1)  // 自动生成的toString
}
```

### 协程示例
```kotlin
import kotlinx.coroutines.*

class CoroutineDemo {
    // 简单协程
    fun launchExample() {
        GlobalScope.launch {
            println("Starting long running task")
            delay(2000)  // 不会阻止线程
            println("Task completed")
        }
    }
    
    // async获取结果
    suspend fun fetchDataAsync(): String {
        return withContext(Dispatchers.IO) {
            delay(1000)
            "Data from network"
        }
    }
    
    // 组织多个异步操作
    suspend fun parallelOperations() {
        val deferred1 = async { fetchData1() }
        val deferred2 = async { fetchData2() }
        
        val result1 = deferred1.await()
        val result2 = deferred2.await()
        
        println("Result1: $result1, Result2: $result2")
    }
    
    // Flow - 响应式流
    fun produceNumbers(): Flow<Int> {
        return flow {
            for (i in 1..5) {
                delay(100)
                emit(i)
            }
        }
    }
    
    suspend fun flowExample() {
        produceNumbers()
            .map { it * 2 }
            .collect { value ->
                println("Received: $value")
            }
    }
    
    suspend fun fetchData1(): String = withContext(Dispatchers.IO) {
        delay(100)
        "Data1"
    }
    
    suspend fun fetchData2(): String = withContext(Dispatchers.IO) {
        delay(100)
        "Data2"
    }
}
```

### 扩展函数和DSL
```kotlin
// 扩展函数
fun String.isEmailValid(): Boolean {
    return this.contains("@") && this.contains(".")
}

fun <T> List<T>.middle(): T? {
    return if (isEmpty()) null else this[size / 2]
}

// DSL构建器
data class HtmlElement(
    val tag: String,
    val attributes: MutableMap<String, String> = mutableMapOf(),
    val children: MutableList<HtmlElement> = mutableListOf()
)

class HtmlBuilder {
    private val elements = mutableListOf<HtmlElement>()
    
    fun div(init: HtmlBuilder.() -> Unit): HtmlElement {
        val builder = HtmlBuilder()
        builder.init()
        return HtmlElement("div").apply {
            children.addAll(builder.elements)
        }
    }
    
    fun p(text: String) {
        elements.add(HtmlElement("p").apply {
            children.add(HtmlElement("text:" + text))
        })
    }
}

fun html(init: HtmlBuilder.() -> Unit): HtmlElement {
    val builder = HtmlBuilder()
    builder.init()
    return HtmlElement("html").apply {
        children.addAll(builder.elements)
    }
}

// 使用DSL
fun dslExample() {
    val email = "user@example.com"
    println(email.isEmailValid())
    
    val numbers = listOf(1, 2, 3, 4, 5)
    println(numbers.middle())  // 3
    
    val document = html {
        p("Hello")
        p("World")
    }
}
```

### Java互操作性
```kotlin
// Kotlin调用Java
import java.io.File

fun javaInteropsDemo() {
    val lines = File("data.txt").readLines()  // List<String>?
    
    // Kotlin处理Java返回的可能为null的集合
    val firstLine = lines?.firstOrNull() ?: "No data"
}

// 为Java提供接口的Kotlin代码
fun getStringSupplier(): () -> String {
    return { "Hello from Kotlin" }
}

// Platform types转换为显式类型
@JvmName("processItems")
fun process(items: List<String>) {
    items.forEach { println(it) }
}
```

