Scala将值赋入隐式范围而不命名

时间:2014-05-06 10:13:08

标签: scala implicit spray-json

使用spray-json时,我需要为我要序列化的每个域类型JsonFormat[A]带一个A隐式作用域。

建议的方法是创建一个自定义对象,其中包含所有隐含字段:

object MyJsonProtocol extends DefaultJsonProtocol {
  implicit val colorFormat = jsonFormat4(Color)
}

import MyJsonProtocol._

我的应用有很多域类型,其中一些域名很长。我的MyJsonProtocol变得越来越难以理解:

object MyJsonProtocol extends DefaultJsonProtocol {
  ... // many more here
  implicit val someClassWithALongNameFormat = jsonFormat4(SomeClassWithALongName)
  implicit val someClassWithALongNameInnerFormat = jsonFormat4(SomeClassWithALongNameInner)
  implicit val someClassWithALongNameVariantBFormat = jsonFormat4(SomeClassWithALongNameVariantB)
  ... // many more here
}

长名字有各种各样的问题:

  • 他们感到多余(名字永远不会被阅读)
  • 他们让我的线条很长
  • 他们引入了复制/粘贴风险,即格式名称与格式类型
  • 不匹配
  • 他们使RHS值不对齐,这隐藏了这里的常见模式

有没有办法在没有命名的情况下将对象带入隐式范围?像这样的东西会更整洁:

object MyJsonProtocol extends DefaultJsonProtocol {
  ... // many more here
  implicit val _ = jsonFormat4(SomeClassWithALongName)
  implicit val _ = jsonFormat4(SomeClassWithALongNameInner)
  implicit val _ = jsonFormat4(SomeClassWithALongNameVariantB)
  ... // many more here
}

...但Scala不允许多个名为“_”的字段。

有没有办法将这些格式带入隐式范围而不将它们全部命名?有没有其他方法可以使用spray-json来避免这个问题?

1 个答案:

答案 0 :(得分:3)

通常,我在配套对象中定义类型类实例:

case class Foo()
object Foo {
  implicit val jsonFormatter = new JsonFormat[Foo] { ... }
}

case class Bar()
object Bar {
  implicit val jsonFormatter = new JsonFormat[Bar] { ... }
}

我不必导入任何东西,因为默认情况下伴随对象包含在隐式搜索范围中,隐式成员都可以具有相同的名称。