Scala:基于表达式进行匹配

时间:2016-10-06 23:24:31

标签: scala pattern-matching

我有一些scala代码,我希望使用scala的模式匹配。代码所做的是获取类的公共getter并将方法名称添加为json键,将方法值添加为json值(如果它是对象或数组,则将其序列化)。这是代码:

private def serialize(any: Any): JsonObject = {
  val json = new JsonObject()
  val rm = scala.reflect.runtime.currentMirror
  val accessors = rm.classSymbol(any.getClass).toType.members.collect {
    case m: MethodSymbol if m.isGetter && m.isPublic => m
  }
  val instanceMirror = rm.reflect(any)
  for (accessor <- accessors) {
    val key = properCase(accessor.name.toString)
    val value = instanceMirror.reflectMethod(accessor).apply()
    if (accessor.returnType <:< typeOf[String]) 
      json.addProperty(key, value.asInstanceOf[String])
    else if (accessor.returnType <:< typeOf[Character]) 
      json.addProperty(key, value.asInstanceOf[Character])
    else if (accessor.returnType <:< typeOf[Boolean]) 
      json.addProperty(key, value.asInstanceOf[Boolean])
    else if (accessor.returnType <:< typeOf[Number]) 
      json.addProperty(key, value.asInstanceOf[Number])
    else if (accessor.returnType <:< typeOf[Iterable[Any]]) 
      json.add(key, serialize(value.asInstanceOf[Iterable[Any]]))
    else
       json.add(key, serialize(value.asInstanceOf[Any]))
  }
  json
}

我想做这样的事情:

accessors match {
  case _.returnType <:< typeOf[String] => json.addProperty(
      properCase(key.name.toString), 
      instanceMirror.reflectMethod(accessor).apply().asInstanceOf[String])
  ...
}

然而,编译器对此非常不满意,说'=>' expected but '.' found。我假设编译器不期望在match语句中使用表达式并且想要一个常量(就像在java中一样)。有没有办法将scala的匹配样式语法与表达式一起使用?

2 个答案:

答案 0 :(得分:1)

要进行模式匹配测试,请编写

case x if x.returnType <:< typeOf[String] => ...

答案 1 :(得分:0)

有可能在中途到达如下:

accessors.foreach { accessor =>
  val key = properCase(accessor.name.toString)
  val value = instanceMirror.reflectMethod(accessor).apply()
  value match {
    case s: String => json.addProperty(key, s);
    case c: Character => json.addProperty(key, c);
    case b: Boolean => json.addProperty(key, b);
    case n: Number => json.addProperty(key, n);
    case i: Iterable[Any] => json.add(key, serialize(i))
    case _ => json.add(key, serialize(value))
  }
}

尽管如此,这并不是基于表达式匹配的。