web-dev-qa-db-ja.com

Scalaの最終クラスとシールドクラスの違いは何ですか?

Scalaには2種類の修飾子があります:finalsealed

それらの違いは何ですか?いつ他を上に使うべきですか?

48
user1187135

finalクラスは、期間を延長できません。

sealed特性は、宣言されているのと同じソースファイルでのみ拡張できます。これは、ADT(代数データ型)の作成に役立ちます。 ADTは、その派生型のsumによって定義されます。

例えば。:

  • Option[A]Some[A] + None
  • List[A]:: + Nil

sealed trait Option[+A]

final case class Some[+A] extends Option[A]
object None extends Option[Nothing]

なぜならOption[A]は封印されているため、他の開発者が拡張することはできません。拡張すると、意味が変更されます。

Some[A]は、期間を延長できないため最終的なものです。


追加のボーナスとして、特性が封印されている場合、パターンマッチが完全ではない場合、コンパイラは警告することができますknows that Option is limitedSomeおよびNoneへ。

opt match {
    case Some(a) => "hello"
}

警告:完全一致ではない場合があります。次の入力では失敗します:None

88
dcastro

sealedクラス(または特性)は、引き続き同じソースファイルに継承できます(finalクラスはまったく継承できません)。

基本クラスのサブクラスの数を制限する場合は、sealedを使用します(「代数データ型」を参照)。

このような制限の非常に実用的な利点の1つとして、コンパイラーは非厳格なパターン一致について警告することができます。

sealed trait Duo
case class One(i:Int) extends Duo
case class Two(i:Int, j:Int) extends Duo

def test(d:Duo) {
  match {
    case One(x) => println(x) // warning since you are not matching Two
  }
}
8
agschaid