我試圖制定一個將任意值轉換爲Json表示並且在未定義轉換的情況下編譯時錯誤的經典示例。隱式轉換不適用
到目前爲止,我有,
trait Json
trait ConvertableToJson[A] {
def toJson: Json
}
object Json {
case class Str(str: String) extends Json
case class Int(int : Int) extends Json
case class StrToJson(s: String) extends ConvertableToJson[StrToJson] {
override def toJson: Json = Str(s)
}
}
implicit def str2Json(s: String): StrToJson = StrToJson(s)
def toJson[A <: ConvertableToJson[A]](a: A) = a.toJson
println(toJson("some string"))
我希望上面的代碼一樣的工作:
toJson("some string")
失敗而不implicit def
編譯。因爲String <: ConvertableToJson[String]
是錯誤的。
但後來用,implicit def
並找到Str2Json
。
Str2Json <: ConvertableToJson[Str2Json]
應該是正確的。
不過,這並沒有發生,編譯器抱怨:
Error: Inferred type arguments [String] do not conform to method toJson's type parameter bounds [A <: scalaz.ConvertToJson.ConvertableToJson[A]]
println(toJson("dhruv"))
^
這將是巨大的,如果有人能幫助我糾正我的理解
我明白String不延伸ConvertableToJson [字符串]這就是爲什麼我所定義的隱含DEF str2Json與簽名,字符串 - > ConvertableToJson(StrToString)。在我的理解中,通過這個隱式def,scala編譯器應該能夠將String轉換爲ConvertableToJson [StrToString],它應該與toJson很好地配合。當然,它不起作用,你的實現,但我仍然不明白爲什麼我的工作。謝謝! :) –
再看看它可以工作,如果你把'toJson'的定義改爲'def toJson [A](a:ConvertableToJson [A])= a.toJson'。隱式轉換僅在將值傳遞到採用不同類型的變量/參數時觸發。它們不會觸發通用參數類型。 (如果您將通用參數從「ConvertableToJson」中刪除,您的代碼將繼續工作,因爲它從不使用。 – iain