例類(Case classes)和普通類差不多,只有幾點關鍵差別,接下來的介紹將會涵蓋這些差別。樣例類非常適合用于不可變的數據。
定義一個樣例類
一個最簡單的樣例類定義由關鍵字case class
,類名,參數列表(可為空)組成:
case class Book(isbn: String)val frankenstein = Book("978-0486282114")
注意在實例化樣例類Book
時,并沒有使用關鍵字new
,這是因為樣例類有一個默認的apply
方法來負責對象的創建。
當你創建包含參數的樣例類時,這些參數是公開(public)的val
case class Message(sender: String, recipient: String, body: String)
val message1 = Message("guillaume@quebec.ca", "jorge@catalonia.es", "?a va ?")println(message1.sender) // prints guillaume@quebec.ca
message1.sender = "travis@washington.us" // this line does not compile
你不能給message1.sender
重新賦值,因為它是一個val
(不可變)。在樣例類中使用var
也是可以的,但并不推薦這樣。
比較
樣例類在比較的時候是按值比較而非按引用比較:
case class Message(sender: String, recipient: String, body: String)val message2 = Message("jorge@catalonia.es", "guillaume@quebec.ca", "Com va?")
val message3 = Message("jorge@catalonia.es", "guillaume@quebec.ca", "Com va?")
val messagesAreTheSame = message2 == message3 // true
盡管message2
和message3
引用不同的對象,但是他們的值是相等的,所以message2 == message3
為true
。
拷貝
你可以通過copy
方法創建一個樣例類實例的淺拷貝,同時可以指定構造參數來做一些改變。
case class Message(sender: String, recipient: String, body: String)
val message4 = Message("julien@bretagne.fr", "travis@washington.us", "Me zo o komz gant ma amezeg")
val message5 = message4.copy(sender = message4.recipient, recipient = "claire@bourgogne.fr")
message5.sender // travis@washington.us
message5.recipient // claire@bourgogne.fr
message5.body // "Me zo o komz gant ma amezeg"
上述代碼指定message4
的recipient
作為message5
的sender
,指定message5
的recipient
為”claire@bourgogne.fr”,而message4
的body
則是直接拷貝作為message5
的body
了。