使用密封的特徵和案例物件

擴充套件 Enumeration 的另一種方法是使用 sealed case 物件:

sealed trait WeekDay

object WeekDay {
  case object Mon extends WeekDay
  case object Tue extends WeekDay
  case object Wed extends WeekDay
  case object Thu extends WeekDay
  case object Fri extends WeekDay
  case object Sun extends WeekDay
  case object Sat extends WeekDay
}

sealed 關鍵字保證特徵 WeekDay 不能在另一個檔案中擴充套件。這允許編譯器做出某些假設,包括已經列舉了 WeekDay 的所有可能值。

一個缺點是此方法不允許你獲取所有可能值的列表。要獲得這樣的列表,必須明確提供:

val allWeekDays = Seq(Mon, Tue, Wed, Thu, Fri, Sun, Sat)

案例類也可以擴充套件 sealed 特徵。因此,可以混合物件和案例類來建立複雜的層次結構:

sealed trait CelestialBody
    
object CelestialBody {
  case object Earth extends CelestialBody
  case object Sun extends CelestialBody
  case object Moon extends CelestialBody
  case class Asteroid(name: String) extends CelestialBody
}

另一個缺點是無法訪問 sealed 物件的列舉的變數名,或者通過它進行搜尋。如果你需要與每個值關聯的某種名稱,則必須手動定義:

  sealed trait WeekDay { val name: String }

  object WeekDay {
      case object Mon extends WeekDay { val name = "Monday" }
      case object Tue extends WeekDay { val name = "Tuesday" }
      (...)   
  }

要不就:

  sealed case class WeekDay(name: String)
    
  object WeekDay {
      object Mon extends WeekDay("Monday")
      object Tue extends WeekDay("Tuesday")
      (...)   
  }