简体   繁体   English

是否可以匹配Scala中的清单类型?

[英]Is it possible to match on the type of a manifest in Scala?

I'm writing some code in Scala that depends a the type parameter that I can't see on an argument. 我在Scala中编写了一些代码,它依赖于我在参数上看不到的类型参数。

def read[T](json: String)(implicit m: Manifest[T]): T = {
  if (m <:< manifest[Map[String, Any]]) {
    JsonParser.jsonToMap(json).asInstanceOf[T]
  } else {
    throw new UnsupportedOperationException("Not implemented for type %s".format(m))
  }
}

Apart from the fact that I'm writing my own json framework, which is probably a pretty bad idea... 除了我正在编写自己的json框架之外,这可能是一个非常糟糕的主意......

Can I use a case statement instead of the if statements, or should I be thinking in a different direction? 我可以使用case语句而不是if语句,还是应该考虑另一个方向?

A much better idea in situations like these where you feel tempted to use sequences of tests against manifests or classes (or type casing more generally) is to use a type class. 在这种情况下,如果你觉得想要对清单或类使用一系列测试(或更普遍地输入套管),那么更好的想法是使用类型类。 In this particular case it would look like, 在这种特殊情况下它看起来像,

// Type class
trait JsonReader[T] {
  def apply(json : String) : T
}

// Type class instance for type Map[String, Any]
implicit def mapReader = new JSonReader[Map[String, Any]] {
  def apply(json : String) =
    JsonParser.jsonToMap(json).asInstanceOf[Map[String, Any]]
}

def read[T](json : String)(implicit reader : JsonReader[T]) : T = reader(json)

You should add type instances for all of the types that you care about. 您应该为您关心的所有类型添加类型实例。

You can now call your read function as follows, 您现在可以按如下方式调用读取函数,

read[Map[String, Any]](... some json ...)

Note that now if you attempt to call it with a type parameter corresponding to a type for which you haven't provided a type class instance the result will be an error at compile time rather than an UnsupportedOperationException at runtime. 请注意,现在如果尝试使用与未提供类型类实例的类型对应的类型参数调用它,则结果将在编译时出错,而不是在运行时出现UnsupportedOperationException

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM