私はScalaで効果的に列挙型である何かを実装しようとしています。コンパイラが非網羅的なパターンの一致を検出できるように、caseクラスを使用してこれを実行したいと思います。
これは、非常に基本的な形式で正常に機能します。例:
sealed abstract class HorizontalAlignment
case object Left extends HorizontalAlignment
case object Right extends HorizontalAlignment
case object Center extends HorizontalAlignment
case object AsIs extends HorizontalAlignment
...
def test (x : HorizontalAlignment) =
x match {
case Left => ...
...
}
ただし、ケースオブジェクトの名前が簡単に衝突する可能性があるため、これは理想的ではありません。
sealed abstract class HorizontalAlignment
case object Left extends HorizontalAlignment
case object Right extends HorizontalAlignment
case object Center extends HorizontalAlignment
case object AsIs extends HorizontalAlignment
sealed abstract class VerticalAlignment
case object Top extends VerticalAlignment
case object Bottom extends VerticalAlignment
case object Center extends VerticalAlignment
case object AsIs extends VerticalAlignment
// "Center" and "AsIs" clash
明らかな解決策は、ケースオブジェクトを別々の名前空間に配置することです。
sealed abstract class HorizontalAlignment {
case object Left extends HorizontalAlignment
case object Right extends HorizontalAlignment
case object Center extends HorizontalAlignment
case object AsIs extends HorizontalAlignment
}
sealed abstract class VerticalAlignment {
case object Top extends VerticalAlignment
case object Bottom extends VerticalAlignment
case object Center extends VerticalAlignment
case object AsIs extends VerticalAlignment
}
しかし、マッチブロックでそれらのクラスを参照する方法は?
Javaスタイルのドットで参照することはできません。
def test (x : HorizontalAlignment) =
x match {
case HorizontalAlignment.Left => 0 // error: not found: value HorizontalAlignment
}
「#」記号も機能していないようです。
def test (x : HorizontalAlignment) =
x match {
case HorizontalAlignment#Left => 0 // error: '=>' expected but '#' found
}
また、このフォームも機能しません。
def test (x : HorizontalAlignment) =
x match {
case _ : HorizontalAlignment#Left => 0 // error: type Left is not a member of Test.HorizontalAlignment
}
この場合、「左」は型ではなくインスタンスであるため、これは理にかなっています。型を参照する簡単な方法があると思います。それを達成するために私が得ることができる最も近いものはこれです:
sealed abstract class HorizontalAlignment {
case class Left extends HorizontalAlignment
case class Right extends HorizontalAlignment
case class Center extends HorizontalAlignment
case class AsIs extends HorizontalAlignment
object Left
object Right
object Center
object AsIs
}
しかし、これによりマッチブロックのコンパイルは正常になりますが、実際にこれらのオブジェクトを参照する方法を見つけることができませんでした。たとえば、この「列挙」のメンバーを関数に渡すことができませんでした。これは、HorizontalAlignmentが型であり、オブジェクトではないため、フィールドアクセスを使用してネストされたオブジェクトの1つを参照することができないためです。一方、これらのオブジェクトは型ではないため、 「#」記号。
クラスの外部からクラスにネストされたオブジェクトを参照する方法はありますか?
編集
これまでのところ、パッケージオブジェクトがこの問題を解決するための最良の方法であることがわかりました。
package object HorizontalAlignment {
sealed abstract class HorizontalAlignment
case object Left extends HorizontalAlignment
case object Right extends HorizontalAlignment
case object Center extends HorizontalAlignment
case object AsIs extends HorizontalAlignment
}
package object VerticalAlignment {
sealed abstract class VerticalAlignment
case object Top extends VerticalAlignment
case object Bottom extends VerticalAlignment
case object Center extends VerticalAlignment
case object AsIs extends VerticalAlignment
}
object Test {
import HorizontalAlignment.HorizontalAlignment
import VerticalAlignment.VerticalAlignment
def test (x : HorizontalAlignment, y : VerticalAlignment) = {
x match {
case HorizontalAlignment.Left => ...
...
}
y match {
case VerticalAlignment.Top => ...
...
}
}
def testTest = test (HorizongalAlignment.Left, VerticalAlignment.Top)
}
ただし、上記の質問(クラス内のネストされたオブジェクトへのアクセス)は引き続き有効です。