在Scala中使用通用的Case类

19
我想知道在Scala case类中使用泛型是否可以减少样板代码。
假设我有以下类层次结构,来模拟一个“变量”类型,它可以打包一组类型,并允许使用模式匹配进行解包:
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的使用/匹配进行全面性检查。
2个回答

28

尝试

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"
}

1
对于问题的第二部分,有两种限制允许类型的方法。
第一种是对类型设置边界,这将限制可允许的类型,但不会允许编译器进行有意义的完整性检查,因为类型可以在任何地方或任何时间定义。
第二种是将类型包装在密封特质中,但这样你实际上为每种类型创建了一个case类,所以你可以删除额外的包装层,直接创建DoubleBox、StringBox等。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接