ジェニーリックとタイプ不変性
ジェニーリック
コトリンを勉強していたとき、ジェニーリックの概念が現れた.
実際、以前javaを勉強していたときは、一度は議論した概念でしたが、特に考えずに閲覧しました.今から見れば、全く分からない概念になった.そこで、この機会に整理しておきたいと思います.
まず辞書の意味を確認します.
ウィキペディアでジェニーンリックを検索すると、以下のような内容が出てきます.
1つの値が複数の異なるデータ型を有することができる技術に重点を置くことで、データ型に依存せずに再利用性を向上させるプログラミング方法.
難解.
ジェニリック氏は、コードの再使用を防止し、タイプの安定性を低下させる措置だと述べた.(例えば、値をパラメータとしてAny[JavaではObject]]から受信した場合→タイプ安定性の低下)
したがって、Genericを使用して、複数のデータ型を使用できるコードを記述することができる.
実際、すべてのプログラミングが文字で読むのは理解できません.サンプルで検証します.
タイプ不変性
まず,Freitクラスとそれをそれぞれ継承するBannaクラスとOrangeクラスを作成する.
タイプ不変性の例open class Fruit
class Banana : Fruit()
class Orange : Fruit()
fun main() {
fun receiveFruits(fruits: Array<Fruit>) {
println("Number of fruits: ${fruits.size}")
}
val bananas:List<Banana> =listOf()
receiveFruits(bananas)
}
上記のコードを入力することで、コンパイルエラーを確認できます.
関数のパラメータは、Arrayタイプをパラメータとして使用することが望ましいが、Arrayタイプがパラメータに組み込まれているため、タイプ不一致コンパイルエラーをチェックすることができる.
実際、ジェニーリックに概念がある前に、私はそれが当たり前だと知っていました.受け継がれた概念自体が子に親に関する情報があるので、Arrayを通して伝えてもバナナには果物に関する情報があります.
しかし、事実はそうではない.
これは、コトリン、ジェニーンリックのタイプの不変性の概念によって発生した状況です.
では、このタイプの不変性がどのような理由で必要かをサンプルコードで決定します.
タイプ不変性が必要な理由の例コードopen class Fruit
class Banana : Fruit()
class Orange : Fruit()
fun main() {
val bananas: Array<Banana> = arrayOf(Banana())
receiveFruits(bananas)
}
fun receiveFruits(fruits: Array<Fruit>) {
fruits[0] = Orange() // 바나나 배열에 오렌지를 넣으면 문제가 됨
}
ArrayオブジェクトをパラメータとしてArrayを受信するパラメータに渡すことができる場合、Bannaを含む果物にOrangeオブジェクトが含まれ、問題が発生します.BannaとOrangeは同じタイプと見なされないからです.
すなわち,コトリンではBannaがFruitを継承してもArrayをArrayに渡すことができず,Generickのタイプを安定させることができる.しかし、次のコードを見てみましょう.open class Fruit
class Banana : Fruit()
class Orange : Fruit()
fun main() {
val bananas: List<Banana> = listOf(Banana(),Banana())
receiveFruits(bananas)
}
fun receiveFruits(fruits: List<Fruit>) {
println(fruits.size) // 2
}
以上のコードは正常に動作しています.私はただArrayをlistに変えただけです.
理由を知るためには、まずコートリンでのArrayとListを知る必要があります.
Arrayはコトリンで可変とされている.これに対して、Listは不変と見なされる.これを検証するために、ArrayドキュメントとListドキュメントをそれぞれチェックします.
Array-ドキュメント
リスト→ドキュメント
リストの宣言簿をチェックすると、リストとして宣言が表示されます.逆に、ArrayはArrayとして宣言される.この両者の違いはoutというキーワードがあるかどうかです.
この件については、後で検討します.
まず、リストはListであるため、cottlinコンパイラは共変性を許可し、上記のコードを許可する.
共変性については、後で話します.
Reference
この問題について(ジェニーリックとタイプ不変性), 我々は、より多くの情報をここで見つけました
https://velog.io/@cjh8746/제네릭과-타입-불변성
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
まず,Freitクラスとそれをそれぞれ継承するBannaクラスとOrangeクラスを作成する.
タイプ不変性の例
open class Fruit
class Banana : Fruit()
class Orange : Fruit()
fun main() {
fun receiveFruits(fruits: Array<Fruit>) {
println("Number of fruits: ${fruits.size}")
}
val bananas:List<Banana> =listOf()
receiveFruits(bananas)
}
上記のコードを入力することで、コンパイルエラーを確認できます.関数のパラメータは、Arrayタイプをパラメータとして使用することが望ましいが、Arrayタイプがパラメータに組み込まれているため、タイプ不一致コンパイルエラーをチェックすることができる.
実際、ジェニーリックに概念がある前に、私はそれが当たり前だと知っていました.受け継がれた概念自体が子に親に関する情報があるので、Arrayを通して伝えてもバナナには果物に関する情報があります.
しかし、事実はそうではない.
これは、コトリン、ジェニーンリックのタイプの不変性の概念によって発生した状況です.
では、このタイプの不変性がどのような理由で必要かをサンプルコードで決定します.
タイプ不変性が必要な理由の例コード
open class Fruit
class Banana : Fruit()
class Orange : Fruit()
fun main() {
val bananas: Array<Banana> = arrayOf(Banana())
receiveFruits(bananas)
}
fun receiveFruits(fruits: Array<Fruit>) {
fruits[0] = Orange() // 바나나 배열에 오렌지를 넣으면 문제가 됨
}
ArrayオブジェクトをパラメータとしてArrayを受信するパラメータに渡すことができる場合、Bannaを含む果物にOrangeオブジェクトが含まれ、問題が発生します.BannaとOrangeは同じタイプと見なされないからです.すなわち,コトリンではBannaがFruitを継承してもArrayをArrayに渡すことができず,Generickのタイプを安定させることができる.しかし、次のコードを見てみましょう.
open class Fruit
class Banana : Fruit()
class Orange : Fruit()
fun main() {
val bananas: List<Banana> = listOf(Banana(),Banana())
receiveFruits(bananas)
}
fun receiveFruits(fruits: List<Fruit>) {
println(fruits.size) // 2
}
以上のコードは正常に動作しています.私はただArrayをlistに変えただけです.理由を知るためには、まずコートリンでのArrayとListを知る必要があります.
Arrayはコトリンで可変とされている.これに対して、Listは不変と見なされる.これを検証するために、ArrayドキュメントとListドキュメントをそれぞれチェックします.
Array-ドキュメント
リスト→ドキュメント
リストの宣言簿をチェックすると、リストとして宣言が表示されます.逆に、ArrayはArrayとして宣言される.この両者の違いはoutというキーワードがあるかどうかです.
この件については、後で検討します.
まず、リストはListであるため、cottlinコンパイラは共変性を許可し、上記のコードを許可する.
共変性については、後で話します.
Reference
この問題について(ジェニーリックとタイプ不変性), 我々は、より多くの情報をここで見つけました https://velog.io/@cjh8746/제네릭과-타입-불변성テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol