样例类(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("[email protected]", "[email protected]", "Ça va ?")
println(message1.sender) // prints [email protected]
message1.sender = "[email protected]" // this line does not compile
你不能给message1.sender
重新赋值,因为它是一个val
(不可变)。在样例类中使用var
也是可以的,但并不推荐这样。
比较
样例类在比较的时候是按值比较而非按引用比较:
case class Message(sender: String, recipient: String, body: String)
val message2 = Message("[email protected]", "[email protected]", "Com va?")
val message3 = Message("[email protected]", "[email protected]", "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("[email protected]", "[email protected]", "Me zo o komz gant ma amezeg")
val message5 = message4.copy(sender = message4.recipient, recipient = "[email protected]")
message5.sender // [email protected]
message5.recipient // [email protected]
message5.body // "Me zo o komz gant ma amezeg"
上述代码指定message4
的recipient
作为message5
的sender
,指定message5
的recipient
为”[email protected]”,而message4
的body
则是直接拷贝作为message5
的body
了。