为什么即使不导入 jvalue2monadic 也能将 JValue 隐式转换为 MonadicJValue?

Why can JValue be implicitly converted to MonadicJValue even if jvalue2monadic is not imported?

在json4s中,代码可以这样写:

import org.json4s._
import org.json4s.jackson.JsonMethods._
...
val x: MonadicJValue = JObject()

这是正确的,因为函数

implicit def jvalue2monadic(jv: JValue) = new MonadicJValue(jv)

由第一个 import org.json4s._ 行导入范围。

(source of jvalue2monadic defination on github)

不过,我又试了一段代码,效果也不错:

import org.json4s.{JObject, MonadicJValue}
import org.json4s.jackson.JsonMethods.parse
...
val x: MonadicJValue = JObject()

由于隐式函数没有导入到这个作用域,我不知道它是如何工作的!

我终于从postWhere does Scala look for implicits?

那里得到了答案

From the book "Programming in Scala, 2nd Edition" which is based on Scala 2.8, I learned the implicit rules that the scala compiler will look for implicit definitions in the companion object of the source or target types, however I didn't learn that the scala compiler will also look for implicit definitions in the outer object for nested types.

在上面的问题中,隐式定义

implicit def jvalue2monadic(jv: JValue) = new MonadicJValue(jv)

在包对象 org.json4s 中定义,它是包层次结构中的外部对象,嵌套 JValue/JObjectMonadicJValue。所以,jvalue2monadic肯定会在需要的时候被scala编译器使用。