未在Scala/Playframework中编译隐式toJson函数的元组3

未在Scala/Playframework中编译隐式toJson函数的元组3,scala,playframework,Scala,Playframework,Tuple-2在Playframework中执行隐式JSON调用时起作用: def toJson(itemTuple: List[((Item, ItemOption), List[Picture])]) : JsObject = { ... } 我定义了一个隐式Writes方法,一切正常。在这种情况下,我可以在“外部”JSON块中传递这样的列表: "items" -> Json.toJson(itemTupleList) 并且它在每个元素上执行隐式方法“toJson”。但是,当我将其

Tuple-2在Playframework中执行隐式JSON调用时起作用:

def toJson(itemTuple: List[((Item, ItemOption), List[Picture])]) : JsObject = { ... }
我定义了一个隐式Writes方法,一切正常。在这种情况下,我可以在“外部”JSON块中传递这样的列表:

"items" -> Json.toJson(itemTupleList)
并且它在每个元素上执行隐式方法“toJson”。但是,当我将其扩展到Tuple-3时,它失败了:

def toJson(itemTuple: List[((Item, ItemOption, ItemAttribute), List[Picture])]) : JsObject = { ... }
这将产生:

sbt.PlayExceptions$CompilationException: Compilation error[No Json deserializer found for type List[(models.butik.Item, models.butik.ItemOption, models.butik.ItemAttribute)]. Try to implement an implicit Writes or Format for this type.]
我想我做到了:

implicit val iW = new Writes[((Item, ItemOption, ItemAttribute), List[Picture])] { ... }
这是什么原因?没有隐式方法(我对Scala有点陌生),还有其他方法可以达到同样的效果吗

(顺便说一句:之所以将项目数据拆分为三个容器,是因为Slick所依赖的Scala的22个元组元素。)

这对我很有用:

import play.api.libs.json._

object Scratch {

  def main(args: Array[String]): Unit = {
    println(toJson(List(((1, 2, 3), List(3)))))
  }

  def toJson(itemTuple: List[((Item, ItemOption, ItemAttribute), List[Picture])]) : JsValue =
    Json.toJson(itemTuple)

  implicit val iW: Writes[((Item, ItemOption, ItemAttribute), List[Picture])] = new Writes[((Item, ItemOption, ItemAttribute), List[Picture])] {
    def writes(x: ((Item, ItemOption, ItemAttribute), List[Picture])) = Json.parse("[1, 2, 3, [3]]") // TODO
  }

  type Item = Int
  type ItemOption = Int
  type ItemAttribute = Int
  type Picture = Int
}

确保注释隐式的返回类型,而不是使用推断类型。如果隐式出现在您需要的地方,而返回类型不显式,编译器将不考虑它。如果它真的这样做了,类型推断可能会陷入糟糕的循环

顺便说一句,您可以使用类型别名稍微清理代码:

 def toJson(itemTuple: List[Record]): JsValue =
    Json.toJson(itemTuple)

  implicit def recordWrite: Writes[Record] = new Writes[Record] {
    def writes(rec: Record) = {
      Json.parse("{}") // TODO
    }
  }

  type Record = ((Item, ItemOption, ItemAttribute), List[Picture])
  type Item = Int
  type ItemOption = Int
  type ItemAttribute = Int
  type Picture = Int
}
 def toJson(itemTuple: List[Record]): JsValue =
    Json.toJson(itemTuple)

  implicit def recordWrite: Writes[Record] = new Writes[Record] {
    def writes(rec: Record) = {
      Json.parse("{}") // TODO
    }
  }

  type Record = ((Item, ItemOption, ItemAttribute), List[Picture])
  type Item = Int
  type ItemOption = Int
  type ItemAttribute = Int
  type Picture = Int
}