如何以编程方式确定该类是一个案例类还是一个简单的类?

Dim*_*arf 14 scala class

如何以编程方式确定给定的类是一个案例类还是一个简单的类?

yǝs*_*ǝla 22

使用新的Scala反射API:

scala> class B(v: Int)
defined class B

scala> case class A(v: Int)
defined class A

scala> def isCaseClassOrWhat_?(v: Any): Boolean = {
     |   import reflect.runtime.universe._
     |   val typeMirror = runtimeMirror(v.getClass.getClassLoader)
     |   val instanceMirror = typeMirror.reflect(v)
     |   val symbol = instanceMirror.symbol
     |   symbol.isCaseClass
     | }
isCaseClassOrWhat_$qmark: (v: Any)Boolean

scala> class CaseClassWannabe extends Product with Serializable {
     |   def canEqual(that: Any): Boolean = ???
     |   def productArity: Int = ???
     |   def productElement(n: Int): Any = ???
     | }
defined class CaseClassWannabe

scala> isCaseClassOrWhat_?("abc")
res0: Boolean = false

scala> isCaseClassOrWhat_?(1)
res1: Boolean = false

scala> isCaseClassOrWhat_?(new B(123))
res2: Boolean = false

scala> isCaseClassOrWhat_?(A(321))
res3: Boolean = true

scala> isCaseClassOrWhat_?(new CaseClassWannabe)
res4: Boolean = false
Run Code Online (Sandbox Code Playgroud)

  • 这很棒......但你需要一个类的实例来检测它.可以只使用类型信息吗?毕竟问题是检测`class`是否是一个案例类而不是实例是来自案例类. (2认同)

axe*_*l22 3

目前(2011),您可以使用反射来查明该类是否实现了该接口scala.Product

scala> def isCaseClass(o: AnyRef) = o.getClass.getInterfaces.find(_ == classOf[scala.Product]) != None
isCaseClass: (o: AnyRef)Boolean

scala> isCaseClass(Some(1))
res3: Boolean = true

scala> isCaseClass("")
res4: Boolean = false
Run Code Online (Sandbox Code Playgroud)

这只是一个近似值 - 您可以进一步检查它是否有一个copy方法,它是否实现Serializable,是否有一个具有适当applyunapply方法的伴生对象 - 本质上,使用反射检查案例类所期望的所有内容。

下一版本中出现的 scala 反射包应该会使案例类检测更容易、更精确。

编辑:

您现在可以使用新的 Scala Reflection 库来完成此操作 - 请参阅其他答案。