本文的内容源于对Scala官网关于case class的教程的翻译。
CASE CLASSES
Case classes are like regular classes with a few key differences which we will go over. Case类适合作为模式固定的数据模型。在教程的下一章,我们将会看到case类在模式匹配(pattern matching)中的作用。
定义一个case类
case类最简洁的定义方式包含关键词case class
、类名称和参数列表(可为空):
case class Book(isbn: String)
val frankenstein = Book("978-0486282114")
注意到实例化Book
类没有用关键字new
,因为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
重新赋值,因为它是个常量。在case类中使用变量(var
)也是可以的,不过不建议这样做。
比较
判断两个case类是否相等(==)时,是通过比较它们的结构(structure)而不是引用(reference):
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
的recipient
成了message5
的sender
,而body
则被直接拷贝。