Case类和常规类有几个关键差异。Case类适用于模型化不可变数据。之后会在模式匹配中展示如何使用Case类。
定义Case类
最简单的Case类只需要关键字case class
,标识符和一个参数列表(可能为空):
case class Book(isbn: String)
val frankenstein = Book("978-0486282114")
注意,下面的示例没有使用new
关键字实例化Message
这个Case类。这是因为Case类默认有一个apply
方法用于对象构造。
当使用参数创建Case类时,参数是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
(不可变的)。也可以在Case类中使用var
,但是不建议这样做。
比较
Case类通过结构不是引用进行比较。
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
是不同的对象,但每个对象的值是相等的。
拷贝
只用copy
方法可以创建一个Case类实例的深拷贝。可以随意改变构造函数的参数。
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
的收件人成为message5
的发件人,但是message4
的body被直接拷贝了。
网友评论