Files
wehub-resource-sync d48cda4081
CI / Test (ubuntu-latest, Node 18.x, bun) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, npm) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, pnpm) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, yarn) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 20.x, bun) (push) Failing after 17m13s
CI / Test (ubuntu-latest, Node 20.x, npm) (push) Failing after 18m42s
CI / Test (ubuntu-latest, Node 20.x, pnpm) (push) Failing after 15m0s
CI / Test (ubuntu-latest, Node 20.x, yarn) (push) Failing after 49m44s
CI / Test (ubuntu-latest, Node 22.x, bun) (push) Failing after 51m55s
CI / Test (ubuntu-latest, Node 22.x, pnpm) (push) Failing after 21m57s
CI / Test (ubuntu-latest, Node 22.x, npm) (push) Failing after 37m39s
CI / Test (ubuntu-latest, Node 22.x, yarn) (push) Failing after 34m7s
CI / Validate Components (push) Failing after 37m15s
CI / Python Tests (push) Failing after 10m1s
CI / Security Scan (push) Failing after 10m1s
CI / Lint (push) Failing after 17m12s
CI / Coverage (push) Failing after 20m19s
CI / Test (macos-latest, Node 18.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, yarn) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, yarn) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, yarn) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 11:55:55 +08:00

3.2 KiB
Raw Permalink Blame History

paths
paths
**/*.kt
**/*.kts

Kotlin コーディングスタイル

このファイルは common/coding-style.md を Kotlin 固有のコンテンツで拡張します。

フォーマット

  • ktlint または Detekt でスタイルを強制
  • 公式 Kotlin コードスタイル(gradle.propertieskotlin.code.style=official

不変性

  • var よりも val を優先 — デフォルトは val、ミューテーションが必要な場合のみ var を使用
  • 値型には data class を使用する; public API では不変コレクション(ListMapSet)を使用
  • 状態更新にはコピーオンライト: state.copy(field = newValue)

命名

Kotlin の慣例に従う:

  • camelCase — 関数とプロパティ
  • PascalCase — クラス、インターフェース、オブジェクト、型エイリアス
  • SCREAMING_SNAKE_CASE — 定数(const val または @JvmStatic
  • インターフェースの接頭辞は振る舞いで付ける、I ではない: Clickable であって IClickable ではない

Null 安全性

  • !! は使用しない — ?.?:requireNotNull()、または checkNotNull() を優先
  • スコープ付き null 安全操作には ?.let {} を使用
  • 正当に結果がない可能性がある関数からは nullable 型を返す
// BAD
val name = user!!.name

// GOOD
val name = user?.name ?: "Unknown"
val name = requireNotNull(user) { "User must be set before accessing name" }.name

シールド型

閉じた状態階層のモデリングにはシールドクラス/インターフェースを使用する:

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

シールド型に対しては常に網羅的な when を使用する — else ブランチは使わない。

拡張関数

ユーティリティ操作には拡張関数を使用するが、発見しやすくする:

  • レシーバー型にちなんだファイル名にする(StringExt.ktFlowExt.kt
  • スコープを限定する — Any や過度に汎用的な型に拡張を追加しない

スコープ関数

適切なスコープ関数を使用する:

  • let — null チェック + 変換: user?.let { greet(it) }
  • run — レシーバーを使って結果を計算: service.run { fetch(config) }
  • apply — オブジェクトの設定: builder.apply { timeout = 30 }
  • also — 副作用: result.also { log(it) }
  • スコープ関数の深いネストは避ける(最大2レベル)

エラーハンドリング

  • Result<T> またはカスタムシールド型を使用
  • throwable コードのラッピングには runCatching {} を使用
  • CancellationException は絶対にキャッチしない — 常に再スローする
  • 制御フローに try-catch を使用しない
// BAD — 制御フローに例外を使用
val user = try { repository.getUser(id) } catch (e: NotFoundException) { null }

// GOOD — nullable 戻り値
val user: User? = repository.findUser(id)