Scala - Case Class

Parametric Field 的預設 Access Level 提升成 public

class RedBull(energy: Int) // 沒加 val 的 parametric field ,access level 是 private
case class BlueBull(energy: Int) // case class  parameteric field 沒有 val 預設即是 public
val red = new RedBull(100)
red.energy // 無法直接存取 private field
//Error:(48, 7) value energy is not a member of RedBull
//red.energy
//^

val blue = new BlueBull(90)
blue.energy // 存取 public field OK 的
// fine

自動實作 Value Compare 的 equals method

class Cat(val weight: Int, val isBlack: Boolean)
case class CaseCat(val weight: Int, val isBlack: Boolean)
val cats = (new Cat(20, true), new Cat(20, true)) // 兩個帶有一樣成員數值的 object
println("cats._1 == cats._2: " + (cats._1 == cats._2))

val case_cats = (new CaseCat(20, true), new CaseCat(20, true)) // 兩個帶有一樣成員數值的 object
println("case_cats._1 == case_cats._2: " + (case_cats._1 == case_cats._2))
Output
cats._1 == cats._2: false // 沒有實作 equals,無法正確比較數值
case_cats._1 == case_cats._2: true // 能夠一一比較成員數值

漂亮的的 toString,能夠一一顯示各個成員數值

val (cat, _) = cats
val (case_cat, _) = case_cats
println("cat: " + cat)
println("case_cat: " + case_cat)  
cat: Cat@1936f0f5 // 預設的 toString 都是 class 名稱加上一段 hashCode
case_cat: CaseCat(20,true) // case class 的 toString,以 constructor 型式,秀出每個成員的數值

能夠在 Pattern Match 使用 Constructor Pattern

val getWeight = cat match {
  case Cat(w, b) => w
}
//Error:(29, 10) not found: value Cat
//    case Cat(w, b) => w
//       ^
// 無法使用 constructor pattern 來取出成員的 weight 變數。


val getCaseWeight = case_cat match {
    case CaseCat(w, b) => w
}
// fine

自動在 Companion Object 中實作 Factory method

val another_cat = Cat(30, true) // 沒有實作 Factory method ,一定要跟一般 class 一樣加上 new 才行
//Error:(39, 21) not found: value Cat
//  val another_cat = Cat(30, true)
//                    ^

val another_cat = new Cat(30, true) // fine

val another_case_cat = CaseCat(30, true) // fine, 不用使用 new keyword 來產生新物件用法更自然

Full script

https://gist.github.com/ot32em/685c7b546f5e74360580

Reference

http://www.artima.com/pins1ed/case-classes-and-pattern-matching.html
http://stackoverflow.com/questions/2312881/what-is-the-difference-between-scalas-case-class-and-class
http://en.wikipedia.org/wiki/Algebraic_data_type

comments powered by Disqus