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 语法。

是否有可能使我想要的工作或者这是一个坏主意而我只是没有得到什么?

编辑: Vinicius 回答了我的问题,但看着答案我还有另一个问题。是否有可能以某种方式提示编译器只有某些类型列表可用于参数 TypedBox?我希望确保编译器仍然可以对 TypedBox 的使用/匹配进行详尽的检查。

4

2 回答 2

27

尝试

sealed abstract class Box;

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

def typeName2(b: Box) = b match {
  case TypedBox(v: Double) => "Double"
  case TypedBox(v: String) => "String"
  case TypedBox(v: Boolean) => "Boolean"
  case _ => "Unknown"
}
于 2013-09-17T19:35:55.997 回答
1

对于问题的第二部分,有两种方法可以限制允许的类型。

第一个是对类型进行限制,这将限制允许的类型,但不允许编译器进行有意义的完整性检查,因为类型几乎可以在任何地方或任何时间定义。

第二个是将类型包装在一个密封的特征中,但是你实际上是为每种类型创建一个案例类,所以你最好删除额外的包装层并简单地创建DoubleBox,StringBox等。

于 2015-09-11T15:40:28.083 回答