提供地道 Kotlin 模式与最佳实践,帮助构建健壮高效且易维护的应用。
复制安装指令,让 AI 自动完成配置 · 推荐新手
请帮我安装 askskill 上的 "kotlin-patterns" 技能: 1. 下载 https://raw.githubusercontent.com/affaan-m/ECC/main/skills/kotlin-patterns/SKILL.md 2. 保存为 ~/.claude/skills/kotlin-patterns/SKILL.md 3. 装好后重载技能,告诉我可以用了
请检查这段 Kotlin 协程代码是否符合最佳实践,并重构为更安全、更易维护的写法:包含结构化并发、异常处理、取消传播与 Dispatcher 使用建议。
返回改进后的 Kotlin 代码,并附上逐项优化说明与潜在风险提示。
帮我为一个 Kotlin 数据层设计更地道的空安全 API,要求减少 !! 的使用,合理利用可空类型、密封类与 Result 模式,并给出示例代码。
给出 API 设计方案、示例实现,以及为何这样更安全易维护的说明。
请为一个配置系统设计 Kotlin DSL,遵循 idiomatic Kotlin 风格,使用 builder、作用域函数和类型安全构建器,并展示完整示例。
输出 DSL 设计、核心代码示例、使用方式,以及可读性和扩展性建议。
Idiomatic Kotlin patterns and best practices for building robust, efficient, and maintainable applications.
This skill enforces idiomatic Kotlin conventions across seven key areas: null safety using the type system and safe-call operators, immutability via val and copy() on data classes, sealed classes and interfaces for exhaustive type hierarchies, structured concurrency with coroutines and Flow, extension functions for adding behaviour without inheritance, type-safe DSL builders using @DslMarker and lambda receivers, and Gradle Kotlin DSL for build configuration.
Null safety with Elvis operator:
fun getUserEmail(userId: String): String {
val user = userRepository.findById(userId)
return user?.email ?: "[email protected]"
}
Sealed class for exhaustive results:
sealed class Result<out T> {
data class Success<T>(val data: T) : Result<T>()
data class Failure(val error: AppError) : Result<Nothing>()
data object Loading : Result<Nothing>()
}
Structured concurrency with async/await:
suspend fun fetchUserWithPosts(userId: String): UserProfile =
coroutineScope {
val user = async { userService.getUser(userId) }
val posts = async { postService.getUserPosts(userId) }
UserProfile(user = user.await(), posts = posts.await())
}
Kotlin's type system distinguishes nullable and non-nullable types. Leverage it fully.
// Good: Use non-nullable types by default
fun getUser(id: String): User {
return userRepository.findById(id)
?: throw UserNotFoundException("User $id not found")
}
// Good: Safe calls and Elvis operator
fun getUserEmail(userId: String): String {
val user = userRepository.findById(userId)
return user?.email ?: "[email protected]"
}
// Bad: Force-unwrapping nullable types
fun getUserEmail(userId: String): String {
val user = userRepository.findById(userId)
return user!!.email // Throws NPE if null
}
Prefer val over var, immutable collections over mutable ones.
// Good: Immutable data
data class User(
val id: String,
val name: String,
val email: String,
)
// Good: Transform with copy()
fun updateEmail(user: User, newEmail: String): User =
user.copy(email = newEmail)
// Good: Immutable collections
val users: List<User> = listOf(user1, user2)
val filtered = users.filter { it.email.isNotBlank() }
// Bad: Mutable state
var currentUser: User? = null // Avoid mutable global state
val mutableUsers = mutableListOf<User>() // Avoid unless truly needed
Use expression bodies for concise, readable functions.
// Good: Expression body
fun isAdult(age: Int): Boolean = age >= 18
fun formatFullName(first: String, last: String): String =
"$first $last".trim()
fun User.displayName(): String =
name.ifBlank { email.substringBefore('@') }
// Good: When as expression
fun statusMessage(code: Int): String = when (code) {
200 -> "OK"
404 -> "Not Found"
500 -> "Internal Server Error"
else -> "Unknown status: $code"
}
// Bad: Unnecessary block body
fun isAdult(age: Int): Boolean {
return age >= 18
}
Use data classes for types that primarily hold data.
// Good: Data class with copy, equals, hashCode, toString
data class CreateUserRequest(
val name: String,
val email: String,
val role: Role = Role.USER,
)
// Good: Value class for type safety (zero overhead at runtime)
@JvmInline
value class UserId(val value: String) {
init {
…
通过双评审智能体对结果进行对抗式校验,提升输出发布前的可靠性
提供地道 Go 语言模式与最佳实践,帮助构建健壮高效且易维护的应用