提供惯用 Kotlin 模式与最佳实践,帮助构建稳健高效且易维护的应用
复制安装指令,让 AI 自动完成配置 · 推荐新手
请帮我安装 askskill 上的 "kotlin-patterns" 技能: 1. 下载 https://raw.githubusercontent.com/affaan-m/ECC/main/docs/ja-JP/skills/kotlin-patterns/SKILL.md 2. 保存为 ~/.claude/skills/kotlin-patterns/SKILL.md 3. 装好后重载技能,告诉我可以用了
请将这段使用回调的 Kotlin 网络请求代码重构为基于协程的写法,并说明如何处理异常、取消任务与结构化并发,给出改造后的完整示例和最佳实践说明。
输出基于协程的 Kotlin 重构代码,并附带异常处理、取消机制和结构化并发的实践建议。
请审查下面的 Kotlin 代码,找出不安全的空值处理方式,改写为更符合 Kotlin 惯用法的写法,尽量减少 !!,并解释每处修改原因。
输出改进后的 null 安全代码版本,并逐项说明如何提升可读性、稳定性和可维护性。
我想为 Kotlin 项目设计一个类型安全的 DSL 构建器来生成界面或配置,请给出示例实现、作用域控制方法、常见陷阱以及命名规范建议。
输出一个 Kotlin DSL 构建器示例,并说明如何保证类型安全、可读性和后续扩展性。
堅牢・効率的・保守性の高いアプリケーションを構築するための慣用的な Kotlin パターンとベストプラクティス。
このスキルは 7 つの主要領域にわたって慣用的な Kotlin の規約を適用します: 型システムとセーフコール演算子を使用した null 安全性、val とデータクラスの copy() によるイミュータビリティ、網羅的な型階層のためのシールドクラスとインターフェース、コルーチンと Flow による構造化並行性、継承なしで振る舞いを追加する拡張関数、@DslMarker とラムダレシーバーを使用した型安全 DSL ビルダー、そしてビルド設定のための Gradle Kotlin DSL。
Elvis 演算子を使用した null 安全性:
fun getUserEmail(userId: String): String {
val user = userRepository.findById(userId)
return user?.email ?: "[email protected]"
}
網羅的な結果のためのシールドクラス:
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>()
}
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 の型システムは null 可能型と非 null 型を区別します。これを最大限に活用してください。
// 良い例: デフォルトで非 null 型を使用
fun getUser(id: String): User {
return userRepository.findById(id)
?: throw UserNotFoundException("User $id not found")
}
// 良い例: セーフコールと Elvis 演算子
fun getUserEmail(userId: String): String {
val user = userRepository.findById(userId)
return user?.email ?: "[email protected]"
}
// 悪い例: null 可能型を強制アンラップ
fun getUserEmail(userId: String): String {
val user = userRepository.findById(userId)
return user!!.email // null の場合 NPE をスロー
}
var より val を優先し、ミュータブルコレクションよりイミュータブルコレクションを優先してください。
// 良い例: イミュータブルデータ
data class User(
val id: String,
val name: String,
val email: String,
)
// 良い例: copy() で変換
fun updateEmail(user: User, newEmail: String): User =
user.copy(email = newEmail)
// 良い例: イミュータブルコレクション
val users: List<User> = listOf(user1, user2)
val filtered = users.filter { it.email.isNotBlank() }
// 悪い例: ミュータブルな状態
var currentUser: User? = null // ミュータブルなグローバル状態を避ける
val mutableUsers = mutableListOf<User>() // 本当に必要な場合のみ使用
簡潔で読みやすい関数には式ボディを使用してください。
// 良い例: 式ボディ
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('@') }
// 良い例: 式としての when
fun statusMessage(code: Int): String = when (code) {
200 -> "OK"
404 -> "Not Found"
500 -> "Internal Server Error"
else -> "Unknown status: $code"
}
// 悪い例: 不要なブロックボディ
fun isAdult(age: Int): Boolean {
return age >= 18
}
主にデータを保持する型にはデータクラスを使用してください。
// 良い例: copy、equals、hashCode、toString を持つデータクラス
data class CreateUserRequest(
val name: String,
val email: String,
val role: Role = Role.USER,
)
// 良い例: 型安全性のための値クラス(ランタイムでゼロオーバーヘッド)
@JvmInline
value class UserId(val value: String) {
init {
require(value.isNotBlank()) { "UserId cannot be blank" }
}
}
@JvmInline
value class Email(val value: String) {
init {
require('@' in value) { "Invalid email: $value" }
}
}
fun getUser(id: UserId): User = userRepository.findById(id)
// 良い例: 網羅的な when のためのシールドクラス
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>()
}
fun <T> Result<T>.getOrNull(): T? = when (this) {
is Result.Success -> data
is Result.Failure -> null
is Result.Loading -> null
}
fun <T> Result<T>.getOrThrow(): T = when (this) {
is Result.Success -> data
…
通过双评审智能体对结果进行对抗式校验,提升输出发布前的可靠性
提供惯用Go设计模式与最佳实践,帮助构建稳健高效且易维护的应用