Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala-模式匹配-是否可以检测值是否为case类?_Scala_Pattern Matching - Fatal编程技术网

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
是如何定义的?我喜欢有答案的问题,其中一个解释如何做,另一个解释为什么不能做,特别是当他们都被选中的时候。