大家好,我是William李梓峰奢方,歡迎加入我的Kotlin學(xué)習(xí)之旅搔扁。
今天是我學(xué)習(xí) Kotlin 的第十三天,內(nèi)容是 Data Classes - 數(shù)據(jù)類蟋字。
官方文檔:
Data Classes - 數(shù)據(jù)類
We frequently create a class to do nothing but hold data. In such a class some standard functionality is often mechanically derivable from the data. In Kotlin, this is called a data class and is marked as data
:
我們經(jīng)常創(chuàng)建一個(gè)類卻僅僅是為了裝載數(shù)據(jù)稿蹲。這種(萬惡的 DTO)類的唯一功能就是傳遞數(shù)據(jù)而已。在 Kotlin 里面鹊奖,這種類就叫數(shù)據(jù)類场绿,并用 data 標(biāo)識(shí):
data class User(val name: String, val age: Int)
// 我更喜歡這樣:
data class User(
val name: String,
val age: Int
)
The compiler automatically derives the following members from all properties declared in the primary constructor:
編譯器自動(dòng)地處理所有在主要構(gòu)造器上聲明的形參,生成對(duì)應(yīng)的屬性嫉入,同時(shí)還會(huì)生成一些預(yù)設(shè)方法:
-
equals()
/hashCode()
pair, -
toString()
of the form"User(name=John, age=42)"
, -
componentN()
functions corresponding to the properties in their order of declaration, -
copy()
function (see below).
包括
- equals() / hashCode() 這對(duì)方法,
- toString() 方法璧尸,返回 如 “User(name=John, age=42)” 的字符串咒林,
- componentN() 函數(shù)生成若干,按照那些屬性的聲明順序來生成爷光,這里又跳了垫竞,直接飛到 Destructuring Declarations,
- copy() 方法蛀序,見面欢瞪。
If any of these functions is explicitly defined in the class body or inherited from the base types, it will not be generated.
如果上述這些任何一個(gè)函數(shù)顯式地定義在一個(gè)類體中或從其他父類繼承過來,它則不會(huì)自動(dòng)生成了徐裸。(所以沒事就別繼承了遣鼓,也別手賤自己去定義,用默認(rèn)的挺好的)
To ensure consistency and meaningful behavior of the generated code, data classes have to fulfil the following requirements:
為了確保數(shù)據(jù)一致性和生成有意義的代碼重贺,數(shù)據(jù)類必須滿足以下要求:
The primary constructor needs to have at least one parameter;
All primary constructor parameters need to be marked as
val
orvar
;Data classes cannot be abstract, open, sealed or inner;
(before 1.1) Data classes may only implement interfaces.
主要構(gòu)造器至少要有一個(gè)形參
所有的主要構(gòu)造器形參都要用 val 或 var 標(biāo)明骑祟;
數(shù)據(jù)類不可以用 abstract, open, sealed 或 inner 修飾;
(在 Kotlin1.1 之前)數(shù)據(jù)類只能實(shí)現(xiàn)接口气笙。
Since 1.1, data classes may extend other classes (see Sealed classes for examples).
自從 1.1 版本以來次企,數(shù)據(jù)類都可以 extend(繼承或擴(kuò)展) 其他類。(例如潜圃,密封類缸棵,又跳了)
On the JVM, if the generated class needs to have a parameterless constructor, default values for all properties have to be specified
(see Constructors).
在 JVM 里面,如果已經(jīng)生成的類需要一個(gè)無參構(gòu)造器谭期,那么所有屬性的默認(rèn)都需要被指定(請(qǐng)看 構(gòu)造器堵第,跳回去了吧凉,如果所有字段都有默認(rèn)值,編譯器會(huì)自動(dòng)生成一個(gè)無參構(gòu)造器)
data class User(val name: String = "", val age: Int = 0)
Copying - 復(fù)制
It's often the case that we need to copy an object altering some of its properties, but keeping the rest unchanged.
我們經(jīng)常需要復(fù)制某個(gè)對(duì)象的部分字段型诚。而另外一部分字段不需要改變客燕。
This is what copy()
function is generated for. For the User
class above, its implementation would be as follows:
copy() 方法為此而生。例如上面的 User 類狰贯,就實(shí)現(xiàn)了一個(gè):
// 系統(tǒng)默認(rèn)生成一個(gè) copy()
fun copy(name: String = this.name, age: Int = this.age) = User(name, age)
This allows us to write
我們可以這樣寫
val jack = User(name = "Jack", age = 1)
val olderJack = jack.copy(age = 2) // 直接改變 age 值也搓,而 name 不變
Data Classes and Destructuring Declarations - 數(shù)據(jù)類與解構(gòu)聲明
Component functions generated for data classes enable their use in destructuring declarations:
Component 方法 生成于數(shù)據(jù)類中,相當(dāng)于直接讓其能夠做 解構(gòu)聲明(又跳了)
val jane = User("Jane", 35)
val (name, age) = jane // 這里做了解構(gòu)聲明涵紊,有點(diǎn)像 bash shell 參數(shù)展開
println("$name, $age years of age") // prints "Jane, 35 years of age"
Standard Data Classes - 標(biāo)準(zhǔn)的數(shù)據(jù)類
The standard library provides Pair
and Triple
. In most cases, though, named data classes are a better design choice, because they make the code more readable by providing meaningful names for properties.
標(biāo)準(zhǔn)庫提供 Pair(一對(duì)) 和 Triple(三胞胎)傍妒。大多數(shù)情況下,即便如此摸柄,數(shù)據(jù)類的命名還是一個(gè)更好的設(shè)計(jì)選擇颤练,因?yàn)樗鼈兡軌蜃尨a可讀性更高一些。(Pair 和 Triple 都是 Kotlin 預(yù)設(shè)的類驱负,方便數(shù)據(jù)裝載嗦玖,這里官方更推薦自己寫)