我使用模式匹配来发现我的属性的类型,如下所示:
value match {
case s: String => processString(s)
case l: Long => processLong(l)
case c1: myCaseClass1 => processCaseClass(c1)
case c2: myCaseClass2 => processCaseClass(c2)
case c3: myCaseClass3 => processCaseClass(c3)
case _ => nothingToDo
}
是否可以检测值是否为案例类而不枚举我的所有案例类?
每个case类和元组都默认扩展Product
trait。因此,您可以使用Product捕获案例类和元组。警告:如果正常扩展Product
特征,这可能会将普通类视为案例类。
value match {
case _: Product => //catches all the case class values with tuple values also.
}
如果你想只捕获案例类
value match {
case x: Product if !x.getClass.getName.startsWith("scala.Tuple") =>
//catches all the case classes.
}
scala> case class Dog(name: String)
defined class Dog
scala> case class Cat()
defined class Cat
scala> val value = Dog("foo")
value: Dog = Dog(foo)
scala> value match { case _: Product => println("caught") }
caught
scala> val value = Cat()
value: Cat = Cat()
scala> value match { case _: Product => println("caught") }
caught
不,这是不可能的。案例类只包含一些编译器生成的成员,并且具有编译器生成的伴随对象,但是无论如何都可以手动实现。无法区分案例类和实现相同成员的非案例类。 The Scala Language Specification甚至包括编译器生成成员的确切扩展。
您可以手动编写一个类似于案例类的类,并且无法区分它们。
如果这是在通用上下文中,您可以使用TypeTag
获取有关传入的值类型的更多信息:
scala> :pa
// Entering paste mode (ctrl-D to finish)
import scala.reflect.runtime.universe.{TypeTag, symbolOf}
def foo[T: TypeTag](foo: T) =
if (symbolOf[T].isClass && symbolOf[T].asClass.isCaseClass)
println("It's a case class!")
else
println("Nope :(")
// Exiting paste mode, now interpreting.
scala> case class Foo(a: Int)
defined class Foo
scala> foo(Foo(3))
It's a case class!
scala> foo("bar")
Nope :(