Kotlin Academy · レッスン

ジェネリック制約

型パラメーターに境界を設定します

レッスン 4/413 ステップ

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

型パラメータの制約

ジェネリックで、比較可能な型や基底型を継承する型など、特定の型だけを受け入れたい場合があります。ジェネリック制約は、型パラメータに上限境界を設定します。

デフォルトの上限境界

制約がない場合、型パラメータの上限境界はAny?です。そのため、null許容型を含むすべての型を受け入れます。null非許容型だけを許可するには、Anyを境界に指定します。

fun <T : Any> requireNonNull(value: T): T {
    return value
}

fun main() {
    println(requireNonNull(42))
}

単一の上限境界

T : Boundを使用すると、TがBoundの部分型であることを要求できます。これにより、関数内で境界のメンバーを呼び出せます。

fun <T : Number> sumDoubled(a: T, b: T): Double {
    return a.toDouble() * 2 + b.toDouble() * 2
}

fun main() {
    println(sumDoubled(3, 4))
    println(sumDoubled(1.5, 2.5))
}

Comparable境界

よく使われる境界はComparable<T>です。これにより、<、>、またはcompareToを使って要素を比較できます。

fun <T : Comparable<T>> maxOf2(a: T, b: T): T {
    return if (a > b) a else b
}

fun main() {
    println(maxOf2(3, 9))
    println(maxOf2("apple", "banana"))
}

境界のメンバーを呼び出す

制約付きジェネリックの内部では、コンパイラがTに境界のAPIがあることを認識しています。そのため、キャストせずにこれらのメソッドを直接呼び出せます。

fun <T : CharSequence> describe(value: T): String {
    return "Length is ${value.length}"
}

fun main() {
    println(describe("hello"))
    println(describe(StringBuilder("hi")))
}

whereによる複数の境界

複数の境界を指定するには、where句を使用します。この場合、Tは指定されたすべての制約を満たす必要があります。

fun <T> copyWhenValid(value: T): T
    where T : CharSequence, T : Comparable<T> {
    return value
}

fun main() {
    println(copyWhenValid("text"))
}

クラスの境界

制約はジェネリッククラスにも適用でき、クラスをインスタンス化するときに指定できる型を制限します。

class NumberBox<T : Number>(val value: T) {
    fun asDouble(): Double = value.toDouble()
}

fun main() {
    val box = NumberBox(10)
    println(box.asDouble())
}

制約によって操作を利用可能にする

制約の目的は、操作を利用可能にすることです。T : NumberがなければtoDouble()を呼び出せませんが、境界によってそのメソッドの存在が保証されます。

実践でのnull非許容境界

Anyを境界にすると、コンパイル時にnull許容の引数が拒否されます。これは、null非許容のジェネリック型を要求する便利な方法です。

fun <T : Any> firstNonNull(a: T, b: T): T = a

fun main() {
    println(firstNonNull("x", "y"))
    // firstNonNull(null, "y") would not compile
}

変性との組み合わせ

制約と変性は異なる問題を解決します。変性(in/out)は部分型関係を制御し、制約(:による境界やwhere)は許可する型を制限します。これらは組み合わせて使用できます。

適切な制約の設計

型に備わる機能が必要な場合にだけ制約を追加します。制約が厳しすぎると再利用性が低下し、緩すぎるとキャストが必要になります。使用する操作を提供する、最も汎用的な型を境界に指定してください。

理解度チェック

型パラメータが複数の境界を満たすようにするには、どうすればよいですか?

まとめ

ジェネリック制約では、T : Bound(複数の境界の場合はwhere)を使って上限境界を設定し、境界の操作を利用可能にするとともに、互換性のない型を除外します。Anyを境界にするとnull非許容型が必要になります。変性と組み合わせることで、安全で表現力の高いジェネリックを設計できます。これで「ジェネリクスと変性」コースは完了です。

無料で開始

AI チューターと学ぶ Kotlin — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
51
レッスン
203

よくある質問

「ジェネリック制約」レッスンは無料ですか?

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

「ジェネリック制約」で何を学びますか?

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

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

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

「ジェネリック制約」レッスンにはどのくらい時間がかかりますか?

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

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

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

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

  1. ジェネリック関数とクラス
  2. 宣言側変性
  3. 使用側変性
  4. ジェネリック制約
← Kotlin Academyに戻る