我正在尝试通过spray-json与RescueTime API进行交互。结果形式如下:
{
"notes":"data is an array of arrays (rows), column names for rows in row_headers",
"row_headers":[
"Rank",
"Time Spent (seconds)",
"Number of People",
"Activity",
"Category",
"Productivity"
],
"rows":[
[
1,
16611,
1,
"iTerm",
"Systems Operations",
2
]
]
}
到目前为止,我正试图挖出正确的案例类。这是我到目前为止所得到的:
package test
import spray.json._
case class RescueTimeApiResult(notes: String, row_headers: List[String], rows: List[List[Either[Int, String]]])
object MyJsonProtocol extends DefaultJsonProtocol {
implicit def rescueTimeApiResultFormat[T: JsonFormat] = jsonFormat3(RescueTimeApiResult)
}
private object Tester extends App {
val notes = "data is an array of arrays (rows), column names for rows in row_headers"
val headers = List("Rank", "Time Spent (seconds)", "Number of People", "Activity", "Category", "Productivity")
val entry1 = List(wrapInt(1),
wrapInt(16611),
wrapInt(1),
wrapString("iTerm"),
wrapString("Systems Operations"),
wrapInt(2))
def wrapInt(x: Int): Either[Int, String] = Left(x)
def wrapString(s: String): Either[Int, String] = Right(s)
val rows = List(entry1)
val obj = RescueTimeApiResult(notes, headers, rows)
println(obj)
import MyJsonProtocol._
println(obj.toJson)
}
这一切都很好,但在编译时scalac
产生:
Error:(31, 15) diverging implicit expansion for type spray.json.JsonWriter[test.RescueTimeApiResult]
starting with method rescueTimeApiResultFormat in object MyJsonProtocol
println(obj.toJson)
^
我对分歧的隐性扩张的理解充其量是粗略的。粗略地说,隐式搜索有一个循环。据我了解,toJson
隐式来自spray.json._
导入,它需要JsonWriter
隐式参数。反过来,这由MyJsonProtocol
对象提供。但是,为什么这个特定的隐式参数引入了一个循环超出了我。一种理论是适用于toJson
的{{1}}转换可能会干扰隐式参数解析,但这只是一种预感。
非常感谢任何帮助。
答案 0 :(得分:1)
我找到了一个解决方案,尽管我对一般解释仍然非常感兴趣。
基本上,我将问题简化为MyJsonProtocol
的隐式定义。在我看来,通过将隐式参数声明为def
而不是val
来推迟评估没有多大用处。此外,在删除类型参数时,由于我的用例相当具体,我能够绕过整个分歧的隐式扩展位。