Scala-模式匹配-是否可以检测值是否为case类?
我使用模式匹配来发现我的财产类型,如:Scala-模式匹配-是否可以检测值是否为case类?,scala,pattern-matching,Scala,Pattern Matching,我使用模式匹配来发现我的财产类型,如: 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 =>
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
}
是否可以在不枚举所有案例类的情况下检测值是否为案例类?默认情况下,每个案例类和元组扩展
产品特征。所以,您可以通过使用Product来捕获case类和元组。警告:在正常扩展“代码>产品<代码>特性时,这可能会考虑一个普通类作为case类。
value match {
case _: Product => //catches all the case class values with tuple values also.
}
如果您只想捕获case类,那么
value match {
case x: Product if !x.getClass.getName.startsWith("scala.Tuple") =>
//catches all the case classes.
}
Scala REPL
默认情况下,每个case类和tuple扩展Product
trait。所以,您可以通过使用Product来捕获case类和元组。警告:在正常扩展“代码>产品<代码>特性时,这可能会考虑一个普通类作为case类。
value match {
case _: Product => //catches all the case class values with tuple values also.
}
如果您只想捕获case类,那么
value match {
case x: Product if !x.getClass.getName.startsWith("scala.Tuple") =>
//catches all the case classes.
}
Scala REPL
不,这是不可能的。Case类只包含一些编译器生成的成员,并有一个编译器生成的伴生对象,但无论如何您都可以手动实现。不可能区分案例类和实现相同成员的非案例类。甚至包括编译器生成的成员的精确扩展
您可以手动编写一个行为与case类完全相同的类,并且无法区分它们。不,这是不可能的。Case类只包含一些编译器生成的成员,并有一个编译器生成的伴生对象,但无论如何您都可以手动实现。不可能区分案例类和实现相同成员的非案例类。甚至包括编译器生成的成员的精确扩展
您可以手动编写一个与case类行为完全相同的类,并且无法区分它们。如果这是在一般上下文中,您可以使用类型标记来获取有关传入值类型的更多信息:
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 :(
如果这是在一般上下文中,您可以使用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 :(
这还将捕获所有元组,每个元组不是case类。这将错误地将以下类标识为case类:class Foo(i:Int)extends Product1[Int]{override def_1=i;override def canEqual(than:Any)=true}
这也将捕获所有元组,这将错误地将以下类标识为案例类:class Foo(i:Int)扩展Product1[Int]{override def_1=i;override def canEqual(that:Any)=true}
您似乎问了一个错误的问题。。。想这样做的原因可能是什么?你到底想在这里干什么?processCaseClass
是如何定义的?我喜欢有一个答案解释如何做,另一个答案解释为什么做不到的问题,特别是当他们都被高估时。你似乎问了一个错误的问题。。。想这样做的原因可能是什么?你到底想在这里干什么?processCaseClass
是如何定义的?我喜欢有答案的问题,其中一个解释如何做,另一个解释为什么不能做,特别是当他们都被选中的时候。