2014-07-19 242 views
0

有了這個代碼經與隱式轉換的麻煩斯卡拉

case class Workspace(ident: Long, name: String) 
case class Project(ident: Long, name: String) 

implicit def workspaceJSON: JSONR[Workspace] = new JSONR[Workspace] { 
    def read(json: JValue) = 
    Workspace.applyJSON(field[Long]("id"), field[String]("name"))(json) 
} 

implicit def projectJSON: JSONR[Project] = new JSONR[Project] { 
    def read(json: JValue) = 
    Project.applyJSON(field[Long]("id"), field[String]("name"))(json) 
} 

def parseEnt[T: JSONR](json: JValue): Either[String, T] = 
    fromJSON[T](json).toEither.left.map{ _.toString } 

def fetchProjects(ws: Workspace): Either[String, Project] = { 
    parseEnt(parse("some text")) 
} 

從而未能在parseEnt(parse("some text"))編譯

ambiguous implicit values: both method taskJSON in class Fetcher of type => 
Fetcher.this.JSONR[types.Task] and method workspaceJSON in class Fetcher of type => 
Fetcher.this.JSONR[Fetcher.this.Workspace] match expected type Fetcher.this.JSONR[T] 

有沒有一種方法,以確保階,在這種情況下,我想類型變量T將成爲Project並選擇projectJSON函數來解析它?或者如果我做錯了,那麼它是如何以正確的方式呢?

+0

如果您明確說出您期望解析的內容,那麼該怎麼辦? parseEnt [Project](解析(「一些文本」)) – johanandren

+0

謝謝你,幫助。 – cvb

回答

0

編譯器正在嘗試自動推斷類型T,它必須是東西,它可以從一個String開始生產(多跌少,但具體細節在這裏不重要)

不幸的是,能不能成功,因爲您提供了從StringProjectWorkspace的多個隱式轉換。簡單的解決方案是明確地指出你想生成類型:

parseEnt[Project](parse("some text")) 

這種模式是相當普遍的系列化類型類,你在哪裏映射多個特定類型(在這種情況下String)的通用一個。

+0

我知道編譯器對於使用哪個實例是模糊的,但我覺得它不能從類型的函數'fetchProjects'中輸入類型,我認爲這很清楚,在這種情況下'T'應該是'Project '。似乎我必須閱讀更多關於類型推斷和scala中的暗示。 – cvb