如何匹配Scala“匹配”语句中的类?

时间:2011-08-23 06:35:41

标签: scala

如何使用“匹配”语句来标识类变量的值?以下是无效的,我找不到一个可接受的变体 - 除了if ... else if ... else ...

val c: Class[_] = classOf[Int]
val what = c match { case classOf[Int] => "int!"; case classOf[Float] => "float!" }

编译器抱怨:error: not found: type classOf

当然,我无法使用Class[Int],因为该类型信息已被删除:

c match { case Class[Int] => "int!"; case Class[Float] => "float!" }
error: type Class of type Class does not take type parameters.

我也试过像Int.class这样的变种,但都无济于事。 (而且我真的不想转换为字符串:我觉得让编译器捕获重命名/移动的类非常重要。)

我是否密集,或者我偶然发现了斯卡拉的盲点?

4 个答案:

答案 0 :(得分:28)

详细案例比较有效:

val what = c match {
  case q if q == classOf[Int] => "int!"
  case q if q == classOf[Float] => "float!"
}

当然,作为小写标识符,classOf无论如何都不应直接在case语句中工作。但是,也没有逃脱

case `classOf`[Int]

在这种情况下工作,因此您必须使用if - 警卫。

答案 1 :(得分:20)

如果为它们创建稳定的标识符(即val),则可以匹配类值

scala> val c: Class[_] = classOf[Int]
c: Class[_] = int

scala> val ClassOfInt = classOf[Int]
ClassOfInt: java.lang.Class[Int] = int

scala> val ClassOfFloat = classOf[Float]
ClassOfFloat: java.lang.Class[Float] = float

scala> val what = c match {
     |     case ClassOfInt => "int!"
     |     case ClassOfFloat => "float!"
     | }
what: String = int!

请注意,您无法匹配类型(即Class [Int]),因为擦除意味着Class [T]的不同类型实例化在运行时无法区分...因此下面的警告

scala> val what = c match {
     |     case _: Class[Int] => "int!"
     |     case _: Class[Float] => "float!"
     | }
warning: there were 2 unchecked warnings; re-run with -unchecked for details
what: java.lang.String = int!

答案 2 :(得分:1)

我遇到了同样的问题,并将课程置于一个稳定的标识符中。那不切实际。我发现下一个最好的事情就是要整洁,否则如果'语句。

使用此方法:

  implicit val arg = cls   
  if (is[ClassA]) ...
  else if (is[ClassB]) ...
  ...
  else throw new IllegalArgumentException("Unknown class: " + cls)

我可以写:

activities

答案 3 :(得分:0)

考虑继承:

val what = c match {
  case q if classOf[Int].isAssignableFrom(q) => "int!"
  case q if classOf[Float].isAssignableFrom(q)  => "float!"
}