ケースクラスはこれから論じるいくつかの差異はあるものの普通のクラスと似ています。 ケースクラスは不変なデータを作るのに適しています。 このツアーの次のステップでは、パターンマッチングでのそれらの有用性を解説します。
ケースクラスの宣言
最小のケースクラスにはキーワードcase class、識別子、パラメータリスト(空かもしれません)が必要です。
case class Book(isbn: String)
val frankenstein = Book("978-0486282114")
ケースクラスBookをインスタンス化する時キーワードnewが使われていないことに気をつけてください。
これはケースクラスがオブジェクトの生成を行うapplyメソッドを標準で保有するためです。
パラメータ有りでケースクラスを作ると、パラメータはパブリックのvalとなります。
case class Message(sender: String, recipient: String, body: String)
val message1 = Message("[email protected]", "[email protected]", "Ça va ?")
println(message1.sender) // [email protected] が出力されます
message1.sender = "[email protected]" // この行はコンパイルされません
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が異なるオブジェクトを参照していたとしても、それぞれのオブジェクトの値は等価となります。
コピー
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として使われますが、message4の定数bodyは直接コピーされます。