假设您定义了以下案例类:
case class CaseClass(i: Int, s: String)
通过模式匹配,您可以通过以下方式实现您想要的:
import scala.reflect.runtime.universe._
typeOf[CaseClass].members.filter(!_.isMethod).map(_.typeSignature).foreach {
case t if t == typeOf[Int] => print("i")
case s if s == typeOf[String] => print("s")
}
为什么?
那么为什么第一次尝试不起作用?
那是因为在您的代码中使用了类型模式。类型模式在运行时检查要匹配的主题的类型 - 在这种情况下是类型签名。因此,通过使用_: Int,我们要求在运行时针对CaseClass 的非方法成员的每个类型签名进行类型检查。
但在这种情况下,我们需要的是值匹配。
让我们仔细看看(使用 Scala REPL):
scala> case class CaseClass(i: Int, s: String)
defined class CaseClass
scala> typeOf[CaseClass]
res1: reflect.runtime.universe.Type = CaseClass
scala> typeOf[CaseClass].members
res2: reflect.runtime.universe.MemberScope = Scopes(method equals, method toString, ..)
scala> typeOf[CaseClass].members.filter(!_.isMethod)
res4: Iterable[reflect.runtime.universe.Symbol] = SynchronizedOps(value s, value i)
scala> typeOf[CaseClass].members.filter(!_.isMethod).map(_.typeSignature)
res5: Iterable[reflect.runtime.universe.Type] = List(String, scala.Int)
所以我们要匹配的是reflect.runtime.universe.Type 类型。请注意,在最后一行中,String 和 scala.Int 只是这些类型的字符串表示形式,而不是它们的实际类型!
所以我们需要将它们与这种类型的不同值进行匹配,我们可以通过typeOf[Int] 和typeOf[String] 轻松获得。
更多关于 Scala 中的模式匹配
您可能希望使用以下代码使代码更简洁:
typeOf[CaseClass].members.withFilter(!_.isMethod).map(_.typeSignature).foreach {
case typeOf[Int] => print("i") // Won't Compile!
case typeOf[Int] => print("s") // Won't Compile
}
但这会给你以下编译错误:
not found: type typeOf
这也是因为我们需要匹配一个以大写字母开头的变量名。所以以下工作:
val T = typeOf[Int]
val S = typeOf[String]
typeOf[CaseClass].members.withFilter(!_.isMethod).map(_.typeSignature).foreach {
case T => print("i")
case S => print("s")
}
有关模式匹配的更多详细信息,请参阅Programming in Scala。您将在此处找到模式匹配的详细说明。