括弧の役割
| <> | ジェネリスク C++のテンプレートみたいな(後決め型名みたいな)感じ 構造体やコレクションが使っている型名 |
キャスト
| as | 失敗したときに例外が発生する |
| as? | 失敗したときにnullを返す |
変数宣言時のnull系
| ? | 変数にnullの可能性があるときにつける |
| ! | kotlinでは使わない |
| !! | 変数がnullの時にNull Pointer Exception が発生する |
プライベート関数の書く位置
SwiftUIとの違いを交えながら説明するね。
結論から言うと、Jetpack Composeでは普通はComposable関数の外に書きます。
SwiftUIではこんな感じだったよね。
struct ContentView: View {
var body: some View {
Button("Tap") {
hello()
}
}
private func hello() {
print("Hello")
}
}
これはstructのメンバー関数だから、この位置に書けた。
Jetpack Composeの場合
Composeにはstructやclassではなく、Composableは単なる関数。
@Composable
fun ContentScreen() {
Button(
onClick = {
hello()
}
) {
Text("Tap")
}
}
private fun hello() {
println("Hello")
}
このようにComposable関数の外に書くのが一般的。
ファイル構成
例えば
ContentScreen.kt
なら
@Composable
fun ContentScreen() {
Button(
onClick = {
hello()
}
) {
Text("Tap")
}
}
private fun hello() {
println("Hello")
}
という並びになる。
privateなので、このContentScreen.ktからしか呼べない。
Composable用のprivate関数も同じ
UIを分割したいときも同じ。
@Composable
fun ContentScreen() {
Column {
Header()
Body()
}
}
@Composable
private fun Header() {
Text("Header")
}
@Composable
private fun Body() {
Text("Body")
}
Header()やBody()もファイル内だけで使うならprivateにするのが一般的。
クラスの中に書くこともできる?
もちろんできる。
class Sample {
fun run() {
hello()
}
private fun hello() {
}
}
でもCompose画面は通常クラスではなくトップレベル関数なので、
@Composable
fun SampleScreen() {
}
private fun hello() {
}
こちらの書き方がComposeでは自然。
SwiftUIとの考え方の違い
SwiftUI
struct
├ body
├ private func
└ private var
Compose
.ktファイル
├ @Composable fun Screen()
├ private fun helper()
├ private fun calculate()
└ private @Composable fun Header()
つまり、**「画面 = クラス」ではなく「画面 = 関数」**という考え方になるんだ。
SwiftUI経験者なら、最初は次のルールで書くと迷いにくいよ。
- 公開したい画面 →
@Composable fun XxxScreen() - その画面だけで使うUI部品 →
private @Composable fun - ヘルパー関数 →
private fun - 状態管理やロジック →
ViewModelへ分離
この書き方はComposeのプロジェクトでもよく採用されていて、見通しも良くなります。
静的変数、クラス
1. 静的変数
Javaの
public static int count = 0;
に相当するものは、Kotlinでは通常companion objectに書きます。
class User {
companion object {
var count = 0
}
}
呼び出しは
User.count++
になります。
2. 「静的クラス」はKotlinにはありません
実はKotlinにはstatic classという概念自体がありません。
Javaでは
class Outer {
static class Inner {
}
}
のように書けますが、Kotlinでは
class Outer {
class Inner {
}
}
と書くだけです。
このInnerはデフォルトでstatic扱いになります。
つまり
val inner = Outer.Inner()
と生成できます。
3. Outerのインスタンスを持つ内部クラスにしたい場合
Swiftでいう
class Outer {
class Inner { } // staticみたいなもの
}
ではなく、
外側のインスタンスを参照したいなら
class Outer {
inner class Inner {
fun test() {
println(this@Outer)
}
}
}
このようにinnerを付けます。
つまり
class Inner→ staticみたいなもの(デフォルト)inner class Inner→ Outerのインスタンスを保持
になります。
4. 「静的クラス」を作りたいならobjectを使うことも多い
例えばユーティリティクラスなら
object MathUtil {
fun add(a: Int, b: Int): Int {
return a + b
}
}
呼び出しは
MathUtil.add(1, 2)
Javaの
class MathUtil {
static int add(...)
}
に近い使い方です。
5. Composeでよく見る書き方
Composeではcompanion objectよりも、トップレベル宣言やobjectがよく使われます。
例えば定数なら
private const val MAX_COUNT = 10
をファイルの先頭や末尾に置くことが多いです。
設定値をまとめるなら
object AppConfig {
const val MAX_COUNT = 10
const val APP_NAME = "MyApp"
}
とすることもあります。
Swiftとの対応表
| Swift | Kotlin |
|---|---|
static var | companion object またはトップレベル |
static let | const val(トップレベルまたはobject/companion object内) |
class func | companion object |
enumのケース | enum class |
| 名前空間(Namespace)的な使い方 | object |
Javaのstatic class | 通常のclass(デフォルトでstatic相当) |
SwiftからKotlinへ移ると最初は「staticがない!」と戸惑いますが、Kotlinでは**トップレベル関数・トップレベル定数・object**を活用する設計が一般的です。慣れてくると、むしろコードがすっきり書けると感じることが多いですよ。
Composeの命名規則
Jetpack Composeにおける命名規則は、Googleが公開しているandroidxの公式ガイドラインに基づき、通常のKotlinのコード規約とは一部異なる独自のルールが定められています。
もっとも重要な原則は、「UIを描画する(Unitを返す)コンポーザブル関数は名詞として扱い、大文字(PascalCase)から始める」ということです。
🏛 基本ルール一覧
1. @Composable関数の命名法
- Unitを返す(UIを画面に出力する)関数
- 大文字から始める(PascalCase)
- 必ず「名詞」または「形容詞+名詞」にする(動詞はNG)
- 例:
Button、UserProfileCard、BasicTextField - ※一般的なKotlinの関数(camelCase / 動詞)とは異なるため注意が必要です。
- 値を返す(状態などを計算して返却する)関数
- 小文字から始める(camelCase)
- 通常のKotlin関数ルールに従います。
- 例:
rememberNavController()、calculateOffset()
2. 引数(Parameters)の命名法
- 小文字から始める(camelCase)
- Modifier(修飾子)を渡す引数
- 名前は必ず
modifierとする - 引数リストの一番最初のオプショナル引数として配置する
- 名前は必ず
- コールバック(イベント)を渡す引数
- 「
on+ 動詞の原形(または名詞+動詞)」にする - 例:
onClick: () -> Unit、onValueChange: (String) -> Unit
- 「
3. 状態管理(State)の命名法
- Stateインスタンスを返す関数
- 頭に
rememberをつける - 例:
remember{ mutableStateOf(false) }
- 頭に
- Hoisted State(状態を保持するオブジェクトクラス)
- 「コンポーネント名 +
State」にする - 例:
ScrollState、LazyListState
- 「コンポーネント名 +
4. 定数・Enum値の命名法(Compose特有)
- 深く不変(Deeply Immutable)な定数やEnum値
- 大文字スネーク(
CAPITALS_AND_UNDERSCORES)ではなく、大文字(PascalCase)を使うことが推奨されています。 - 例:
enum class Alignment { Top, Center, Bottom }
- 大文字スネーク(
🎨 コード例で見る正しい書き方
// 1. UIコンポーネントは大文字(PascalCase)の名詞
@Composable
fun UserProfileCard(
username: String,
// 2. 修飾子は一第1オプショナル引数に「modifier」の名前で配置
modifier: Modifier = Modifier,
// 3. イベントコールバックは「on + 動詞」
onFollowClick: () -> Unit
) {
// 4. 内部状態は remember を使用
val isExpanded = remember { mutableStateOf(false) }
Column(modifier = modifier) {
Text(text = username)
Button(onClick = onFollowClick) {
Text(text = "Follow")
}
}
}
🔍 なぜ「大文字+名詞」なのか?
Jetpack Composeにおけるコンポーザブル関数は、「処理を行う関数」ではなく、「概念としてのUIコンポーネント(型)を宣言するもの」として扱われます。そのため、従来の TextView や Button といったJava/Kotlinのクラス(型)と同じような感覚で扱えるよう、大文字から始まる名詞で命名するように設計されています。