Kotlin基本メモ

括弧の役割

<>ジェネリスク
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にはstructclassではなく、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との対応表

SwiftKotlin
static varcompanion object またはトップレベル
static letconst val(トップレベルまたはobject/companion object内)
class funccompanion 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)
    • 例:ButtonUserProfileCardBasicTextField
    • ※一般的なKotlinの関数(camelCase / 動詞)とは異なるため注意が必要です。 
  • 値を返す(状態などを計算して返却する)関数
    • 小文字から始める(camelCase)
    • 通常のKotlin関数ルールに従います。
    • 例:rememberNavController()calculateOffset()

2. 引数(Parameters)の命名法

  • 小文字から始める(camelCase)
  • Modifier(修飾子)を渡す引数
    • 名前は必ず modifier とする
    • 引数リストの一番最初のオプショナル引数として配置する
  • コールバック(イベント)を渡す引数
    • on + 動詞の原形(または名詞+動詞)」にする
    • 例:onClick: () -> UnitonValueChange: (String) -> Unit

3. 状態管理(State)の命名法

  • Stateインスタンスを返す関数
    • 頭に remember をつける
    • 例:remember{ mutableStateOf(false) } 
  • Hoisted State(状態を保持するオブジェクトクラス)
    • 「コンポーネント名 + State」にする
    • 例:ScrollStateLazyListState

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のクラス(型)と同じような感覚で扱えるよう、大文字から始まる名詞で命名するように設計されています。

タイトルとURLをコピーしました