0Pricing
Kotlin Academy · レッスン

インライン値クラス

オーバーヘッドなしでラップします

「インライン値クラス」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。

ラッピングの問題

プリミティブ型をクラスでラッピングすると型安全性が得られますが、通常はヒープ割り当てのコストがかかります。値クラスなら、コンパイラーが可能な場合にラッパーを消去するため、型安全性を保ちながらそのコストを抑えられます。

値クラスの宣言

プライマリコンストラクターにプロパティを1つだけ持つクラスに、@JvmInline value classを付けます。値クラスは独立した型として振る舞います。

@JvmInline
value class Password(val value: String)

fun main() {
    val p = Password("secret")
    println(p.value)
}

独立した型

型エイリアスとは異なり、値クラスは別の型です。Passwordが必要な場所に、通常のStringを誤って渡すことはできません。

@JvmInline
value class Password(val value: String)

fun login(p: Password) = println("login with " + p.value)

fun main() {
    login(Password("hunter2"))
}

オーバーヘッドゼロ

実行時には、コンパイラーが通常、基になる値をインライン化するため、追加のオブジェクト割り当ては発生しません。ほとんどのコードパスで、Passwordは通常のStringとして表現されます。

@JvmInline
value class Meters(val amount: Double)

fun main() {
    val d = Meters(5.0)
    println(d.amount) // stored inline as a Double
}

メソッドとプロパティ

値クラスには、通常のクラスと同じように、関数や計算プロパティを定義できます。

@JvmInline
value class Celsius(val degrees: Double) {
    fun toFahrenheit() = degrees * 9 / 5 + 32
}

fun main() {
    println(Celsius(100.0).toFahrenheit())
}

検証に使うinitブロック

initブロックを使うと、生成時にラップした値を検証できるため、すべてのインスタンスが有効であることを保証できます。

@JvmInline
value class Percentage(val value: Int) {
    init {
        require(value in 0..100) { "out of range" }
    }
}

fun main() {
    println(Percentage(75).value)
}

計算プロパティ

1つだけ保持する値から導出される計算プロパティを追加して、ロジックを型の近くに置くことができます。

@JvmInline
value class Seconds(val value: Int) {
    val asMinutes: Double get() = value / 60.0
}

fun main() {
    println(Seconds(120).asMinutes)
}

インターフェースの実装

値クラスはインターフェースを実装できるため、ポリモーフィックに利用できます。ただし、インターフェース型として扱うとボックス化が発生する場合があります。

interface Describable {
    fun describe(): String
}

@JvmInline
value class Money(val cents: Int) : Describable {
    override fun describe() = "$" + cents / 100.0
}

fun main() {
    println(Money(1599).describe())
}

ボックス化が発生する場合

値をnullable、インターフェース、またはジェネリックコレクションで使用すると、ラッパーが再び現れます(ボックス化)。この場合、コンパイラーは実際のオブジェクトを生成します。正しく動作しますが、効率は低下します。

@JvmInline
value class Id(val raw: Int)

fun main() {
    val direct = Id(1)        // inlined
    val boxed: Id? = Id(2)    // boxed because nullable
    println("" + direct.raw + " " + boxed?.raw)
}

value classとdata classの違い

data classは常に割り当てが発生し、多数のプロパティを保持できます。一方、value classはプロパティを1つだけ保持し、オーバーヘッドゼロを目指します。単一の値を型安全に薄くラップする場合は、値クラスを選びます。

重要な理由

値クラスを使うと、次のことができます。

  • 同じ型のパラメーターを取り違えるのを防ぐ
  • プリミティブ値に検証を付加する
  • 通常は実行時コストをかけない

値クラスは、型エイリアスでは不十分な場合の型安全な解決策です。

理解度チェック

インライン値クラスについての理解度を確認しましょう。

まとめ

インライン値クラスについて、次のことを学びました。

  • プロパティを1つ持つ@JvmInline value classとして宣言する
  • 通常はオーバーヘッドがゼロの独立した型である
  • メソッド、計算プロパティ、initによる検証をサポートする
  • nullable、ジェネリック、またはインターフェースとして使うとボックス化される

次は、実際の利用例を見ていきます。

よくある質問

「インライン値クラス」レッスンは無料ですか?

はい。「インライン値クラス」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。

「インライン値クラス」で何を学びますか?

オーバーヘッドなしでラップします ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Kotlin Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「インライン値クラス」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このKotlin Academyレッスンでコードを書いて実行できますか?

はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 型エイリアス
  2. インライン値クラス
  3. ユースケース
  4. 制限事項
← Kotlin Academyに戻る