【问题标题】:Implicit conversion happens without importing implicit?隐式转换发生而不导入隐式?
【发布时间】:2013-09-17 20:26:29
【问题描述】:

我在 Play Framework 的 Scala 控制台中玩耍,看起来它以某种方式进行了隐式转换,而没有任何隐式定义:

scala> import play.api.libs.json._
import play.api.libs.json._

scala> :implicits
No implicits have been imported other than those in Predef.

scala> Json.arr _
res0: Seq[play.api.libs.json.Json.JsValueWrapper] => play.api.libs.json.JsArray = <function1>

scala> Json.arr(1,2,3)
res1: play.api.libs.json.JsArray = [1,2,3]

如您所见,:implicits 的输出显示范围内唯一的隐式转换是来自scala.Predef 的转换。但是,当我将 Int 值 (1,2,3) 传递给 Json.arr() 时,它们不知何故被转换为 play.api.libs.json.Json.JsValueWrapper 实例。

我的印象是隐式转换仅在隐式转换在范围内时应用(即,它在当前范围内声明或导入)。那么这种转换是如何发生的呢?


更新:我认为 Play 控制台一定在做某事,因为即使我打开一个新控制台并进行简单分配(根本没有导入),转换也会发生:

scala> val x: play.api.libs.json.Json.JsValueWrapper = 1
x: play.api.libs.json.Json.JsValueWrapper = JsValueWrapperImpl(1)

【问题讨论】:

    标签: scala implicit-conversion


    【解决方案1】:

    看起来这是转换: https://github.com/playframework/playframework/blob/eeb155f39d1394ac4fa9a5f6316a9fe0884582b0/framework/src/play-json/src/main/scala/play/api/libs/json/Json.scala#L118

    我相信它是在参数类型的显式范围内找到的,正如这个关于隐含来自哪里的答案中所述: Where does Scala look for implicits?

    【讨论】:

    • 我有 Programming in Scala, 2nd Ed.(我已经通读了一遍),但它是为 Scala 2.8 编写的,根据您的回答在 2.9 中添加了指向参数类型范围事物的链接。这就解释了为什么我不知道它来自哪里,以及为什么它没有出现在:implicits 列表中。谢谢!这些天我可能应该只是阅读语言规范......
    • 我不认为这是不正确的——编译器正在查看 JsValueWrapper 类型的隐式范围并找到我链接的转换
    • @KelseyGilmore-Innis - 我同意(因此我接受你的回答)。我不知道 som-snytt 在说什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-30
    • 2013-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-05
    相关资源
    最近更新 更多