【Scala】 sealedとパターンマッチ
環境 Scala 2.11.8
シールドクラス(トレイト)を継承したサブクラスは、すべて同一のソースファイルに定義される。
そしてシールドクラスをパターンマッチに使用されると、match式の網羅性をコンパイラがチェックできる。
sealedなし
このときはcaseのパターンが全て網羅されなくてもエラーは出ない。
が当然、網羅されていないパターンを投げると実行時エラーになる
trait Msg case class TxtMsg() extends Msg case class ObjMsg() extends Msg case class ErrMsg() extends Msg object Msg { def message(m: Msg): Unit = m match { case TxtMsg() => println("Text") } }
$ scalac Msg.scala $ # エラーは出ない
scala> :load Msg.scala Loading test.scala... defined trait Msg defined class TxtMsg defined class ObjMsg defined class ErrMsg defined object Msg scala> Msg.message(ErrMsg()) scala.MatchError: ErrMsg() (of class ErrMsg) at Msg$.message(<console>:16) ... 33 elided
sealedあり
こうすると、コンパイルエラーになるので安全。
sealed trait Msg case class TxtMsg() extends Msg case class ObjMsg() extends Msg case class ErrMsg() extends Msg object Msg { def message(m: Msg): Unit = m match { case TxtMsg() => println("Text") case ObjMsg() => println("Text") // case ErrMsg() => println("Text") } }
$ scalac test.scala test.scala:8: warning: match may not be exhaustive. It would fail on the following input: ErrMsg() def message(m: Msg): Unit = m match { ^ one warning found