Kotlin-データクラス
4645 ワード
概要
開発の過程で、論理機能がなく、データを保存するために使用されるデータが作成されることがよくあります.Kolinでは,これらのクラスを一括してデータクラスと呼び,キーワードdataでタグ付けする.
data class User(val name: String, val age: Int)
コンパイラは、メインコンストラクタで宣言されたすべてのプロパティに基づいて、次のメンバー関数を自動的に推定します.
データクラスの宣言条件
データクラスにコンストラクション関数があるかどうかは、プライマリコンストラクション関数でメンバー属性を初期化する必要があります.
data class User(val name: String = "", val age: Int = 0)
オブジェクトのコピー
前述したように、JVMはデータクラスのcopy()関数を自動的に生成します.copy()はいったい何に使いますか.copy()はオブジェクトの浅いコピーですか、それとも深いコピーですか.これらの疑問を持って下を見る.
data class Person(var name: String, var age: Int) {
}
data class MyInfo(val no: Int, var person: Person) {
override fun hashCode(): Int {
return super.hashCode()
}
}
fun main(args: Array) {
var per0: Person = Person("A", 20)
var per1: Person = per0.copy(age = 15)
println("------- Log0 -------")
println("per0: $per0")
println("per1: $per1")
println("------- Log1 -------")
per1.name = "B"
println("per0: $per0")
println("per1: $per1")
println("------- Log2 -------")
var info0: MyInfo = MyInfo(1, per0)
var perAA = Person("AA", 30)
var info1: MyInfo = info0.copy(no = 2)
var info2: MyInfo = info0.copy(person = perAA)
println("info0: $info0")
println("info1: $info1")
println("------- Log3 -------")
info1.person.name = "C"
println("info0: $info0")
println("info1: $info1")
println("------- Log4 -------")
println("info0: $info0")
println("info1: $info1")
println("info2: $info2")
println("------- Log5 -------")
info2.person.name = "AC"
println("info0: $info0")
println("info1: $info1")
println("info2: $info2")
println("perAA: $perAA")
}
// Log
------- Log0 -------
per0: Person(name=A, age=20)
per1: Person(name=A, age=15)
------- Log1 -------
per0: Person(name=A, age=20)
per1: Person(name=B, age=15)
------- Log2 -------
info0: MyInfo(no=1, person=Person(name=A, age=20))
info1: MyInfo(no=2, person=Person(name=A, age=20))
------- Log3 -------
info0: MyInfo(no=1, person=Person(name=C, age=20))
info1: MyInfo(no=2, person=Person(name=C, age=20))
------- Log4 -------
info0: MyInfo(no=1, person=Person(name=C, age=20))
info1: MyInfo(no=2, person=Person(name=C, age=20))
info2: MyInfo(no=1, person=Person(name=AA, age=30))
------- Log5 -------
info0: MyInfo(no=1, person=Person(name=C, age=20))
info1: MyInfo(no=2, person=Person(name=C, age=20))
info2: MyInfo(no=1, person=Person(name=AC, age=30))
perAA: Person(name=AC, age=30)
まず2つのデータクラスPersonとMyInfoを作成したが,MyInfoクラスにはPersonメンバー属性があり,PersonとMyInfoインスタンスをそれぞれ作成し,そのcopy()関数をそれぞれ用いて新しいオブジェクトを生成した.
すなわち、copy()関数は、オブジェクトをコピーし、一部のプロパティを変更しますが、他のプロパティは変更されません.copyは単純なレプリケーションではなく、新しいオブジェクトを作成します.基本タイプのプロパティでは値がコピーされ、値が割り当てられますが、参照タイプではアドレスを渡すか、浅いコピーを行うかで、新しいオブジェクトは作成されません.copy()って実际には浅いコピーと深いコピーの组み合わせだと思いますが、よくわかりませんね.
"="番号付与については,浅いコピーが行われていることがよく知られているが,ログ1からは,基本データ型であっても,新しいオブジェクトの基本タイプ属性付与時には,元の値の属性を映像化することができる.
var per0: Person = Person("A", 20)
var per1: Person = per0
------- Log0 -------
per0: Person(name=A, age=20)
per1: Person(name=A, age=20)
------- Log1 -------
per0: Person(name=B, age=20)
per1: Person(name=B, age=20)
「=」番号付与とcopy()は、実行メカニズムに違いがあります.copyを使用する場合は、リファレンスタイプの浅いコピーに注意し、少し注意すると大きなエラーが発生します.の
データの解体
前述したように、JVMはデータクラスからクラスの属性に対応するいくつかの列のコンポーネント関数(componentN()関数群)を生成し、関数名の数字1からNは、属性の宣言順序と一致し、これらのコンポーネント関数があれば、解構宣言でデータを使用することができる.
val jane = Person("Jane", 35)
val (n, a) = jane
println("$n, $a years of age") // "Jane, 35 years of age"