Scala泛型函数与解析对象

时间:2017-07-12 17:04:22

标签: scala generics functional-programming

我需要一个这样的函数(抱歉,我需要null)

def foo[T](json: JsonElement): T = 
json match {
 case x: JsonObject => gson.fromJson(x, classOf[T])
 case _ => null
}

当然这是无法编译的:)

请帮忙!

UPD

有结果函数

def parseObject[T: ClassTag](jo: JsonObject, gson: Gson, name: String): Option[T] = Option(jo.get(name)).map {
  case x: JsonObject =>
    val cTag = implicitly[ClassTag[T]]
    gson.fromJson(x, cTag.runtimeClass.asInstanceOf[Class[T]])

  case _ => null.asInstanceOf[T]
}

def parseArray[T: ClassTag](jo: JsonObject, gson: Gson, name: String): java.util.List[T] = Option(jo.get(name)).map {
  case x: JsonArray =>
    val cTag = implicitly[ClassTag[java.util.List[T]]]
    gson.fromJson(x, cTag.runtimeClass.asInstanceOf[Class[java.util.List[T]]])

  case _ => Collections.emptyList[T]
}.getOrElse(Collections.emptyList[T])

他们运作良好:)

非常感谢大家!

P.S。

最后一个问题

是否有某种方法可以将此函数转换为parsePrimitive [T](jo:JsonObject,name:String):Option [T] = ???

def parseInteger(jo: JsonObject, name: String): Option[Integer] = Option(jo.get(name)).map {
  case x: JsonPrimitive => x.getAsInt
  case _ => null
}

def parseString(jo: JsonObject, name: String): Option[String] = Option(jo.get(name)).map {
  case x: JsonPrimitive => x.getAsString
  case _ => null
}

def parseBoolean(jo: JsonObject, name: String): Option[java.lang.Boolean] = Option(jo.get(name)).map {
  case x: JsonPrimitive => x.getAsBoolean
  case _ => null
}

2 个答案:

答案 0 :(得分:2)

试试这个(使用Option):

import scala.reflect.ClassTag
def foo[T : ClassTag](json: JsonElement): Option[T] = json match {
  case x: JsonObject =>
    val cTag = implicitly[ClassTag[T]]
    Some(gson.fromJson(x, cTag.runtimeClass.asInstanceOf[Class[T]]))
  case _ => None
}

请注意,在调用函数时,您需要知道T是什么。

如果您确实需要null,则可以在检索结果时附加.orNull

如果你真的,真的,真的必须使用null,那么这应该有效:

import scala.reflect.ClassTag
def foo[T <: AnyRef : ClassTag](json: JsonElement): T = json match {
  case x: JsonObject =>
    val cTag = implicitly[ClassTag[T]]
    gson.fromJson(x, cTag.runtimeClass.asInstanceOf[Class[T]])
  case _ => null.asInstanceOf[T] // Required for some odd reason.
}

答案 1 :(得分:0)

良好的Scala风格不鼓励使用null。除此之外,编译器限制哪些类型是无效的。许多基元不能是nullIntBoolean等。)

编译器不知道类型T是否为空,因此不允许使用。如果T可以与某些无效类型子集绑定上下文,则这可能是可能的。 (但Option[T]仍然会更好。)