加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-16 08:55:21 所属栏目:安全 来源:网络整理
导读:我有以下代码,它使用spray-json通过parseJson方法将一些 JSON反序列化为case类. 根据隐式JsonFormat [MyCaseClass]的定义位置(在线或从伴随对象导入),以及在定义时是否提供了显式类型,代码可能无法编译. 我不明白为什么从配对对象导入隐式需要它在定义时具有
我有以下代码,它使用spray-json通过parseJson方法将一些 JSON反序列化为case类.

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

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

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

我正在使用Scala 2.11.7.

Broken Code – 从伴随对象导入的通配符,推断类型:

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","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","c"]}"""
  println(s"Deserialise: ${inputJson.parseJson.convertTo[MyCaseClass]}")
}

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

解决方法

在搜索他的评论中提到的错误消息Huw之后,我能够从2010: Why does this explicit call of a Scala method allow it to be implicitly resolved?找到这个StackOverflow问题

这导致我在2008年创建了这个Scala问题,并于2011年结束:https://issues.scala-lang.org/browse/SI-801(‘隐式转换要求显式结果类型?’)

马丁说:

I have implemented a slightly more permissive rule: An implicit conversion without explicit result type is visible only in the text following its own definition. That way,we avoid the cyclic reference errors. I close for now,to see how this works. If we still have issues we migth come back to this.

这就行了 – 如果我重新排序破解代码以便首先声明伴随对象,那么代码就会编译. (它仍然有点奇怪!)

(我怀疑我没有看到’隐含方法在这里不适用’消息,因为我有一个隐含值而不是转换 – 虽然我在这里假设根本原因与上面相同).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读