scalaのケースクラスについて

scalaのケースクラスについてまとめてみました。

ケースクラスとは、簡単に言うとimmutableなオブジェクトを簡単に生成できるクラスを定義して、パターンマッチで利用できるようにするためのクラス定義方法です。
とのことなんですがやはりこれだけでは理解できないのでブログに残すことに。。。



クラス宣言時に下のようにclassの前にcaseを付けるとケースクラスになります。

case class Iphone(color:String, price:Int)

特徴としては下の5点です。

1,ケースクラスのコンストラクタに指定された引数は、valが付与されているものとして扱われます。(読み取り専用フィールドとして公開される)

2,newキーワードの代わりにIphone(color:String, price:Int)のようにケースクラス名でインスタンスを作成できます。

3,toString,hashCode,equalsの各メソッドが実装されます。

4,copyメソッドが生成されます。

5,パターンマッチのパターンとして利用できるようになります。


1はというと
ケースクラスで宣言することでコンストラクタ引数と同じフィールド名が作成されますが、
valをコンストラクタ引数に付与した時と同様読み込み専用のフィールドとして公開されます。

scala> myIphone.color
res0: String = green

scala> myIphone.color = blue
<console>:10: error: reassignment to val
       myIphone.color = blue
                      ^

2はどういうことかというと、通常のクラスからインスタンスを生成する場合はnewをつけますが、newをつけずにこんな感じでインスタンスを生成できます。

scala> case class Iphone(color:String, price:Int)
defined class Iphone

scala> val myIphone = Iphone("green", 400)
myIphone: Iphone = Iphone(green,400)

3はというと、

//toString
scala> myIphone.toString
res1: String = Iphone(green,400)

//hashCode
scala> myIphone.hashCode
res2: Int = 2048103794

//equals
scala> case class Iphone(color: String, price: Int)
defined class Iphone

scala> val myPhone = Iphone( "green", 900)
myPhone: Iphone = Iphone(green,900)

scala> val hisPhone = Iphone( "green", 900)
hisPhone: Iphone = Iphone(green,900)

//==でequalsメソッドが呼び出される
scala> hisPhone == myPhone
res32: Boolean = true

scala> val herPhone = Iphone( "red", 900)
herPhone: Iphone = Iphone(red,900)

scala> hisPhone == herPhone
res33: Boolean = false

4のcopyメソッドについては↓の記事が参考になりました。
http://j5ik2o.me/blog/2013/06/02/scala-copy-method/
copyメソッドを使えば、ある特定のフィールドのみ値の変更可能になります。

5については次調べようと思っているパターンマッチの時に詳しく説明できたらと。
今はパターンマッチのパターンとしてケースクラスを使えるという理解程度です。
【追記】
scalaのパターンマッチについて - hikonori07’s blog


公式ドキュメントの説明
http://docs.scala-lang.org/tutorials/tour/case-classes.html


Scalaスケーラブルプログラミング第2版

Scalaスケーラブルプログラミング第2版

Scala逆引きレシピ (PROGRAMMER’S RECiPE)

Scala逆引きレシピ (PROGRAMMER’S RECiPE)