LoginSignup
0
0

More than 3 years have passed since last update.

Kotlin Reference 宣言箇所変性

Last updated at Posted at 2019-09-19

この記事は、以下を基本的に引用した内容となっております。
一部翻訳がわかりづらい部分があったため、自分なりにわかりやすく修正した内容となっております。

ジェネリクス - Kotlin Programming Language

記事を読む前に

この記事の内容を理解するためには、ジェネリクスについて知っておく必要があります。
以下サイトが初心者にもわかりやすくまとめられていました。
JavaジェネリックスのPECS原則、extendsとsuperの勘所 -- ぺけみさお
Javaジェネリクス:共変、反変、非変(これ以上簡単にはならない) | GWT Center

この辺について把握していないと、以下の話についていけないかと思います。。

宣言箇所変位

ジェネリックインターフェイスのSource<T>があると仮定します。また、パラメータとしてTを返すメソッドのみを持つとします。


// Java
interface Source<T> {
  T nextT();
}

それはSource<Object>型の変数(呼び出せるコンシューマメソッドがない)内でSource<String>のインスタンスへの参照を保持するのに完全に安全です。 – しかし、Javaはこれを知っているし、まだそれを禁止していません:


// Java
void demo(Source<String> strs) {
  Source<Object> objects = strs; // !!! Java では許可されていない
  // ...
}

これを修正するために、Source<? extends Object>型のオブジェクトを宣言する必要があります。全ての同メソッドを前のような変数で呼ぶことができるので、順序に意味はなく、より複雑な型で追加することに価値はありません。しかし、コンパイラはそれを知りません。

Kotlinでは、コンパイラにこの種の問題を説明する方法があります。これは、 宣言箇所変性と呼ばれています:ソースの 型パラメータTSource<T>のメンバからのみ 返し (プロデュースする)、消費されることがないということを確認するために、アノテーションを付けることができます。これを行うために、我々はout修飾子を提供します。


abstract class Source<out T> {
  abstract fun nextT(): T
}

fun demo(strs: Source<String>) {
  val objects: Source<Any> = strs // これは OK 、なぜなら T はoutパラメータのため
  // ...
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0