変数の理解
「可変性」(Variant)は、クラス階層に及ぼす形式パラメータの影響を表します.次の3つのタイプに分けられます.
TがT`の上位資料型である場合
コトリンは無変性をデフォルト値とした.次の異常が発生する可能性があります.がMutableListのサブタイプである場合、4番目のコードではIntをStringに鋳造できないため、例外が発生します.従って、運転時の安全性においては、無変性が基礎となる.
しかし、不変性のみを原則とすると、共通変数と逆共通変数が必要な場合にコードを記述する際に使用される不要なコード(例えば、タイプ鋳造)が長くなるため、Cottlinはoutとinキーワードを提供してこの問題を解決する.
[図]共通および逆共通の例
outとinの使用上の注意事項をコードで理解します.
outキーワードはin位置(Tタイプをパラメータとする)で作成できません.以下のコードに注記されています.
逆に、inキーを使用すると、out位置でのTの使用は禁止されます(Tタイプとその親タイプを返します).
実際、上図のように、現実の生活では「consumerofplacelbeがどのようにconsumerof竹のサブ資料型になっているのか」という疑問が生じる可能性があります.
ただし、子データ型が親データ型の特例ではなく、子データ型が親データ型を継承し、子データ型から親データ型を受け入れる方法と手順を理解することができます.
この文章は以下の住所の文章を参考にして書いたものです.
ref1 : https://kotlinlang.org/docs/reference/generics.html
ref2 : https://proandroiddev.com/understanding-type-variance-in-kotlin-d12ad566241b
これは私の理解に基づいて書いた文章です.事実と異なる可能性があることを示す.
いつでもコメントでフィードバックを歓迎します
TがT`の上位資料型である場合
コトリンは無変性をデフォルト値とした.次の異常が発生する可能性があります.
val strs: MutableList<String> = mutableListOf()
val objs: MutableList<Any> = strs
// !!! A compile-time error here saves us from a runtime exception later
objs.add(1) // Here we put an Integer into a list of Strings
val s: String = strs[0] // !!! ClassCastException: Cannot cast Integer to String
上記のコードのMutableListしかし、不変性のみを原則とすると、共通変数と逆共通変数が必要な場合にコードを記述する際に使用される不要なコード(例えば、タイプ鋳造)が長くなるため、Cottlinはoutとinキーワードを提供してこの問題を解決する.
[図]共通および逆共通の例
outとinの使用上の注意事項をコードで理解します.
outキーワードはin位置(Tタイプをパラメータとする)で作成できません.以下のコードに注記されています.
class Producer<out T: Music>(private var piece: T) {
fun producePiece(): T = piece
//fun setPiece(piece: T) { !! out으로 선언된 T는 in 위치에 나타날 수 없습니다 !!
// this.piece = piece
//}
}
open class Music
class Metal : Music()
fun main() {
val soundOfMusic = Music()
val ultraMen = Metal()
var person1 = Producer<Music>(soundOfMusic)
var person2 = Producer<Metal>(ultraMen)
// person2 = person1 !! type mismatch !!
}
in位置で使えるなら、person 2.これは、setPiece(SoundOfMusic)のようなコードを記述することができ、生産者がSoundOfMusicの生産者になるためである.
逆に、inキーを使用すると、out位置でのTの使用は禁止されます(Tタイプとその親タイプを返します).
class Consumer<in T>(private var source: T) {
//fun produceSource(): T = source !! in으로 선언된 T는 out 위치에 나타날 수 없습니다 !!
fun setSource(source: T) {
this.source = source
}
}
open class Vegetable
class Bamboo : Vegetable()
fun main() {
val broccoli = Vegetable()
val longBamboo = Bamboo()
var vegeConsumer = Consumer<Vegetable>(broccoli)
var bamboConsumer = Consumer<Bamboo>(longBamboo)
vegeConsumer.setSource(longBamboo) // vegeConsumer can consume longBamboo
//panda.setSource(broccoli) !! type mismatch !!
}
ConsumerオブジェクトはTタイプしか消費できないので、生産できません.
実際、上図のように、現実の生活では「consumerofplacelbeがどのようにconsumerof竹のサブ資料型になっているのか」という疑問が生じる可能性があります.
ただし、子データ型が親データ型の特例ではなく、子データ型が親データ型を継承し、子データ型から親データ型を受け入れる方法と手順を理解することができます.
この文章は以下の住所の文章を参考にして書いたものです.
ref1 : https://kotlinlang.org/docs/reference/generics.html
ref2 : https://proandroiddev.com/understanding-type-variance-in-kotlin-d12ad566241b
これは私の理解に基づいて書いた文章です.事実と異なる可能性があることを示す.
いつでもコメントでフィードバックを歓迎します
Reference
この問題について(変数の理解), 我々は、より多くの情報をここで見つけました https://velog.io/@sangho0n/변성variance의-이해テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol