scala:库正在寻找要声明的隐式值

scala : library is looking for an implicit value to be declared

我正在使用两个进口

import org.json4s._
import org.json4s.native.JsonMethods._

我有以下源代码

val json = parse("~~~~~~aklsdjfalksdjfalkdsf")
var abc = (json \ "something").children map {
        _.extract[POJO]
    }

我运行之后我看到了

Error:(32, 18) No org.json4s.Formats found. Try to bring an instance of org.json4s.Formats in scope or use the org.json4s.DefaultFormats.
        _.extract[POJO]

Error:(32, 18) not enough arguments for method extract: (implicit formats: org.json4s.Formats, implicit mf: scala.reflect.Manifest[POJO])POJO.
Unspecified value parameters formats, mf.
        _.extract[POJO]

我知道我应该声明 :

 implicit val df = DefaultFormats

我学会了如何将 'implicit' 用于我的 scala 代码。 但是我需要了解如何使用强制开发人员在其源代码中定义隐式变量的库。

似乎在错误消息中所述的 ExtractableJsonAstNode class 文件的 'extract' 方法中使用了关键字 'implicit'。

 def extract[A](implicit formats: Formats, mf: scala.reflect.Manifest[A]): A =
    Extraction.extract(jv)(formats, mf)

我看到它正在寻找要在我的源代码中声明的 'implicit' 变量关键字。

第一个问题我怎么知道什么时候一个隐式关键字要用于另一个隐式关键字(例如在库中声明), 将是我定义的操作的开关(如果 'implicit' 不被声明两次) 我唯一的线索是,当母源代码使用 'implicit' 关键字并使用变量时,它的类型是一个特征。然后我(dev)需要声明一个变量,其类型为扩展该特征的具体 class 。不知道是不是真的..

我还在 json 库的 'Formats.scala' 文件中找到了以下源代码。

 class CustomSerializer[A: Manifest](
    ser: Formats => (PartialFunction[JValue, A], PartialFunction[Any, JValue])) extends Serializer[A] {

    val Class = implicitly[Manifest[A]].runtimeClass

    def deserialize(implicit format: Formats) = {
      case (TypeInfo(Class, _), json) =>
        if (ser(format)._1.isDefinedAt(json)) ser(format)._1(json)
        else throw new MappingException("Can't convert " + json + " to " + Class)
    }

    def serialize(implicit format: Formats) = ser(format)._2
  }

注意声明了def deserialize(implicit format: Formats)一旦我在我的文件中写入 'implicit val df = DefaultFormats',它会影响整个 json 机制而不仅仅是 'extract' 方法吗? 因为 CustomSerializer 在 json 图书馆。

总结.. 第一个问题是关于 'implicit' 关键字用法之一。 第二个问题是关于 'implicit' 关键字范围。

When do I use the implicit keyword?

隐式用于定义您通常无法控制的事物的行为。在您的问题中, DefaultFormats 已经是隐含的。你不需要声明一个新的隐式使用它,你可以直接导入它。

至于知道您正在使用的库何时需要一些隐含的范围,那就是错误。它本质上是在告诉你“如果你不确定这个错误是什么,你可以只导入 DefaultFormats.

Will an implicit affect the whole mechanism?

这是一个需要理解的关键问题。

当您有一个接受隐式的函数时,您的编译器将在作用域中搜索该类型的隐式

您的函数正在寻找 org.json4s.Formats。通过导入 DefaultFormat 或编写您自己的类型 Format 的隐式,您正在让您的函数使用该格式。

这对您的其余代码有什么影响?

您拥有的任何 other 函数依赖于作用域中的隐式 Format 将使用相同的隐式。这可能适合你。

如果您需要使用多种不同的格式,您将希望将这些组件彼此分开。您不想在同一范围内定义多个相同类型的隐式。这会让人类和计算机感到困惑,应该避免。