Scala在解决implicits时如何使用显式类型?

时间:2015-09-07 12:26:13

标签: scala implicit spray spray-json

我有以下代码,它使用spray-json通过parseJson方法将一些JSON反序列化为案例类。

根据隐式JsonFormat [MyCaseClass]的定义位置(在线或从伴随对象导入),以及在定义时是否提供了显式类型,代码可能无法编译。

我不明白为什么从配对对象中导入隐式需要它在定义时具有显式类型,但是如果我把它放在内联中,情况并非如此?

有趣的是,IntelliJ在所有情况下都正确地定位了隐式参数(通过cmd-shift-p)。

我正在使用Scala 2.11.7。

损坏的代码 - 来自随播对象的通配符导入,推断类型:

import SampleApp._
import spray.json._

class SampleApp {
  import MyJsonProtocol._
  val inputJson = """{"children":["a", "b", "c"]}"""
  println(s"Deserialise: ${inputJson.parseJson.convertTo[MyCaseClass]}")
}

object SampleApp {
  case class MyCaseClass(children: List[String])

  object MyJsonProtocol extends DefaultJsonProtocol {
    implicit val myCaseClassSchemaFormat = jsonFormat1(MyCaseClass)
  }
}

结果:

Cannot find JsonReader or JsonFormat type class for SampleAppObject.MyCaseClass

请注意,明确导入隐式myCaseClassSchemaFormat会发生同样的事情。

工作代码#1 - 来自随播对象的通配符导入,显式类型:

向伴随对象中的JsonFormat添加显式类型会导致代码编译:

import SampleApp._
import spray.json._

class SampleApp {
  import MyJsonProtocol._
  val inputJson = """{"children":["a", "b", "c"]}"""
  println(s"Deserialise: ${inputJson.parseJson.convertTo[MyCaseClass]}")
}

object SampleApp {
  case class MyCaseClass(children: List[String])

  object MyJsonProtocol extends DefaultJsonProtocol {
    //Explicit type added here now
    implicit val myCaseClassSchemaFormat: JsonFormat[MyCaseClass] = jsonFormat1(MyCaseClass)
  }
}

工作代码#2 - 隐含内联,推断类型:

但是,将隐式参数放在使用它们的位置,不带显式类型,也可以使用!

import SampleApp._
import spray.json._

class SampleApp {
  import DefaultJsonProtocol._

  //Now in-line custom JsonFormat rather than imported
  implicit val myCaseClassSchemaFormat = jsonFormat1(MyCaseClass)

  val inputJson = """{"children":["a", "b", "c"]}"""
  println(s"Deserialise: ${inputJson.parseJson.convertTo[MyCaseClass]}")
}

object SampleApp {
  case class MyCaseClass(children: List[String])
}

0 个答案:

没有答案