Kotlin ジェネリクスの型投影 変位指定 共変でout Anyとは をサンプルコードと共にめちゃ簡単に説明してみる

Kotlin勉強中の私です。Javaから移行組です.

今回、次のようなソースコードを見ていて、疑問に思ったことがいくつかありました。出典は、Android StudioでLoginの機能を自動的に作ってみたところ、Loginの結果を表示するクラスとして、下記のResultクラスが存在しています。

sealed class Result<out T : Any> {

    data class Success<out T : Any>(val data: T) : Result<T>() 
    data class Error(val exception: Exception) : Result<Nothing>()

    override fun toString(): String {
        return when (this) {
            is Success<*> -> "Success[data=$data]" 
            is Error -> "Error[exception=$exception]"
        }
    }
}

特に気になったのは

data class Success<out T : Any>(val data: T) : Result<T>() 

の部分ですね。

ジェネリクスは、Javaでも使っていたので知ってはいましたが、 out ?? ってなりました。

そこで、初めて「変位指定」とか「型投影」とか「不変」「共変」「反変」という言葉たちに出会いました。

もう、いきなりつまずきそうですよね?!字からして、難しそうで、逃げたくなりますよね??

「共変とはなんぞや?変位指定とはなんぞや!?」

と独眼鉄になっちゃいますね(´ω`)

しかも、説明を読んでも、さっぱりわかりませんでした。
特に、outがスーパータイプを指定することはわかりましたが、Anyって指定すると、なんでもいいわけじゃん?なんで必要なの?となりました。

Kotlin公式サイト ジェネリクス
https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/generics.html

自分でコード書いてみたら、腑に落ちました。(もっと早くやれよ)

class Container<T>(var value:T)

上記のように、Containerクラスを作ります。とってもシンプルなクラスですね。ただ単に、入れ物です。value というプロパティだけがあります。

下記のようなshowというメソッドがあって、引数にContainerを指定します。(Android Studioで実行しています。)

    
fun show(container:Container<out Any>){
        Log.d(TAG, container.toString())
}

show()を呼び出します。

val inta:Container<Int> = Container(23)
show(inta)

val stringa:Container<String> = Container("うきき")
show(stringa)

今、ここでIntもStringもshowの引数として入れられましたね?

では、showメソッドの引数を、次のように引数の型指定から「out」をなくしてみます。

 fun show(container:Container<Any>){ //この行からoutがなくなっています。
Log.d(TAG, container.toString())
}
val inta:Container<Int> = Container(23)
show(inta)

val stringa:Container<String> = Container("うきき")
show(stringa)

すると、呼び出し元のshow(inta)、show(stringa)でコンパイルエラーが起こります。

Type mismach.Required Containre<Any>

って出ます。

ああ。つまり、outを指定するのは、Anyのサブタイプならなんでもいいよってためにつけるわけですね。٩( ‘ω’ )و

「ウォーーーーーターーーーー!!!」

とヘレンケラーが叫んだ瞬間もこんな感じだったでしょう。(大げさ)

これが、共変です。

反変はその反対です。(ざっくり)

不変は、outを消したときと同様です。

それにしても共変って日本語わかりにくくないですか??!「共に」「変わる」ってなんだ?オラさっぱりわからなかったぞ!!

初心者なので、理解が間違っているところがあるかもです。(´;ω;`)
ぜひぜひご指摘くださーい。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です