AgentSkillsCN

kotlin

Kotlin 编程,以协程、空安全、扩展函数以及 Android/JVM 开发模式为核心,是 .kt 文件开发的优质选择。

SKILL.md
--- frontmatter
name: kotlin
description: Kotlin programming with coroutines, null safety, extension functions, and Android/JVM development patterns. Use for .kt files.

Kotlin

Modern Kotlin development with coroutines, null safety, and idiomatic patterns.

When to Use

  • Working with .kt files
  • Android app development
  • JVM backend with Spring Boot/Ktor
  • Multiplatform projects (KMP)

Quick Start

kotlin
data class User(
    val id: String,
    val name: String,
    val email: String,
    val createdAt: Instant = Clock.System.now()
)

suspend fun fetchUser(id: String): User? {
    return apiService.getUser(id)
}

Core Concepts

Null Safety

kotlin
// Nullable types
val name: String? = null

// Safe calls
val length = name?.length

// Elvis operator
val len = name?.length ?: 0

// Smart casts
if (name != null) {
    println(name.length) // Smart cast to String
}

// Not-null assertion (use sparingly)
val len = name!!.length

Data Classes & Sealed Classes

kotlin
data class User(
    val id: String,
    val name: String,
    val email: String
)

sealed class Result<out T> {
    data class Success<T>(val data: T) : Result<T>()
    data class Error(val message: String) : Result<Nothing>()
    object Loading : Result<Nothing>()
}

// Exhaustive when
fun handleResult(result: Result<User>) = when (result) {
    is Result.Success -> println(result.data)
    is Result.Error -> println(result.message)
    Result.Loading -> println("Loading...")
}

Common Patterns

Coroutines

kotlin
// Suspend function
suspend fun fetchData(): List<Item> {
    return withContext(Dispatchers.IO) {
        api.fetchItems()
    }
}

// Parallel execution
suspend fun loadDashboard(): Dashboard {
    return coroutineScope {
        val user = async { fetchUser() }
        val orders = async { fetchOrders() }
        Dashboard(user.await(), orders.await())
    }
}

// Flow for streams
fun observeUsers(): Flow<List<User>> = flow {
    while (true) {
        emit(fetchUsers())
        delay(5000)
    }
}.flowOn(Dispatchers.IO)

Extension Functions

kotlin
fun String.isValidEmail(): Boolean {
    return Regex("^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}\$").matches(this)
}

fun <T> List<T>.secondOrNull(): T? = getOrNull(1)

inline fun <T> Result<T>.onSuccess(action: (T) -> Unit): Result<T> {
    if (this is Result.Success) action(data)
    return this
}

Best Practices

Do:

  • Use data classes for DTOs
  • Prefer immutability (val over var)
  • Use sealed classes for state
  • Use coroutines for async work

Don't:

  • Use !! without null check
  • Create utility classes (use extensions)
  • Block main thread with runBlocking
  • Ignore cancellation in coroutines

Troubleshooting

ErrorCauseSolution
NullPointerExceptionForce unwrap on nullUse safe call ?.
CancellationExceptionCoroutine cancelledHandle or propagate
IllegalStateExceptionInvalid state accessCheck state before access

References