2014-08-30 68 views
1

我試圖通過spray-json與RescueTime API接口。結果是這樣的形式:spray-json - diverging implicit expansion

{ 
"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轉換適用於Any可能會干擾隱式參數的分辨率,但這只是一種預感。

任何幫助,非常感謝。

回答

1

我找到了一個解決方案,但我仍對一般的解釋非常感興趣。

本質上,我將問題簡化爲MyJsonProtocol的隱式定義。我想到,通過將隱式參數聲明爲def而不是val,推遲評估沒有多大用處。此外,在刪除類型參數時,由於我的用例比較具體,我能夠解決整個分歧的隱式擴展位。

相關問題