kotlin

kotlin基本構文-ジェネリッック型,ジェネリック関数,共変と反変,out予約語

投稿日:

ジェネリック

プライマリコンストラクタで受け取った文字列をプロパティとして持つオブジェクトを作成し、
その文字列を取得するコードは以下の通り。普通。

この書き方だと、型が文字列に限定される。
型を一般化して、文法で型と紐づける書式がジェネリック。
上記のコードをジェネリックで一般化してみる。
一般化した型引数をTとしている。

型推論による型指定の省略

プライマリコンストラクタに渡すパラメタの型からジェネリック型が唯一決まる場合は、
インスタンス化時の型指定を省略できる。

複数のジェネリック型指定

複数のジェネリック型を指定できる。下記のような書き方になる。

型引数の制約

型引数TをT:typeとすると、type型かtype型の派生型という意味になり、型の制約を作れる。
ジェネリック型をHogeクラスの派生に制限する定義として、インスタンス化時にInt型を指定する例。
コンパイル時(前)にちゃんとエラーが出る。

ジェネリック関数

関数の引数と戻り値を関数の呼び出し時に決めて紐づけられる仕組み。
ジェネリック型の定義はclassだが、ジェネリック関数はclassではなく関数。

以下は、リストの末尾(tail)を応答するジェネリック関数。
引数として配列を取るが、配列の型を呼び出し時に決められる。

共変(covariant)と不変(invariant)

Javaの話。Javaでは配列の要素のクラスに継承関係があるとき、
その配列は親クラスの配列に代入できる。
aaryの定義はNumberの配列だが中身はIntegerの配列になっている。
定義上Numberの配列だから、Numberの派生クラスのインスタンスを代入する式を書いてもコンパイルが通る。
例えば、Longのインスタンスを入れられる。
実態はIntegerの配列だから、Longのインスタンスを入れた瞬間に怒られる。

kotolinの配列は共変ではなく不変。
配列の要素に継承関係があったとしても代入できない。
これを不変(invariant)と言ってkotolinは不変が基本。

ただし、意図的に共変にすることもできる。
以下の通り、kotlinの配列は不変であるから ArrayをArrayに代入できない。
コンパイル時にひっかかる。

out予約語をつけることで、その配列を共変配列にできる!

実際、コレクションのListはoutが指定してある。
なので、それを知らずともJava的に共変配列の操作のようなことができる。

-kotlin
-

Copyright© ikuty.com , 2018 AllRights Reserved Powered by AFFINGER4.