17

Scala ケース クラスにジェネリックを使用すると、定型コードを節約できるのではないかと思います。

次のクラス階層を保存して、型のセットをボックス化し、パターン マッチングを使用してボックス化解除できる「バリアント」型をエミュレートします。

sealed abstract class Box;

case class DoubleBox(v: Double) extends Box;
case class StringBox(v: String) extends Box;
case class BooleanBox(v: Boolean) extends Box;

def typeName(b: Box) = b match {
  case DoubleBox(v) => "Double"
  case StringBox(v) => "String"
  case BooleanBox(v) => "Boolean"
  case _ => "Unknown"
}

リーフ ケース クラスがジェネリックである場合に、それらを処理する方が便利な場所がコード内にある場合があります。何かのようなもの:

sealed abstract class Box;

case class TypedBox[T](v: T) extends Box;

def typeName2(b: Box) = b match {
  case TypedBox[Double](v) => "Double"
  case TypedBox[String](v) => "String"
  case TypedBox[Boolean](v) => "Boolean"
  case _ => "Unknown"
}

しかし、これはコンパイルされません。私が理解している限り、この構文は実際には有効な Scala 構文として認識されていません。

私が望むものを機能させることは可能ですか、それとも悪い考えであり、何かを得られないのですか?

編集:ヴィニシウスは私の質問に答えましたが、答えを見て別の質問があります。特定のタイプのリストのみをパラメーター TypedBox に使用できることを何らかの方法でコンパイラーに示唆することは可能ですか? コンパイラが TypedBox の使用/一致の徹底的なチェックを引き続き実行できることを確認したいと考えています。

4

2 に答える 2

1

質問の 2 番目の部分では、許可されるタイプを制限する方法が 2 つあります。

1つ目は、型に境界を設定することです。これにより、許容される型が制限されますが、型はほとんどどこでもいつでも定義できるため、コンパイラーは意味のある完全性チェックを行うことができなくなります。

2 つ目は、封印されたトレイトで型をラップすることですが、基本的には型ごとにケース クラスを作成することになるため、余分なラップ層を削除してDoubleBoxStringBox、 などを作成することもできます。

于 2015-09-11T15:40:28.083 に答える