私は、parseJson
メソッドを使用してスプレーjsonを使用していくつかのJSONをケースクラスにデシリアライズするコードを用意しています。implicを解決する際にScalaはどのように明示的な型を使用しますか?
暗黙的なJsonFormat [MyCaseClass]が定義されている(インラインまたはコンパニオンオブジェクトからインポートされた)場所と、定義時に明示的な型が指定されているかどうかに応じて、コードがコンパイルされないことがあります。
コンパニオンオブジェクトから暗黙的にインポートする理由を私は理解していないが、それが定義されている時に明示的な型を持っていることが必要ですが、私は、インラインそれを置けば、このケースではありませんか?
興味深いことに、IntelliJはすべてのケースで暗黙のパラメータを(cmd-shift-pを介して)正確に探します。
私はScala 2.11.7を使用しています。
ブロークン・コード - コンパニオンオブジェクトからワイルドカードのインポート、推論されたタイプ:中
import SampleApp._
import spray.json._
class SampleApp {
import MyJsonProtocol._
val inputJson = """{"children":["a", "b", "c"]}"""
println(s"Deserialise: ${inputJson.parseJson.convertTo[MyCaseClass]}")
}
object SampleApp {
case class MyCaseClass(children: List[String])
object MyJsonProtocol extends DefaultJsonProtocol {
implicit val myCaseClassSchemaFormat = jsonFormat1(MyCaseClass)
}
}
結果:同じことが暗黙のmyCaseClassSchemaFormat
の明示的なインポートで発生することを
Cannot find JsonReader or JsonFormat type class for SampleAppObject.MyCaseClass
注意。
ワーキングコード#1 - ワイルドカードは、コンパニオン・オブジェクト、明示的な型からインポート:コンパニオンオブジェクト内JsonFormatに明示的な型を追加
をコンパイルするためのコードを引き起こす:
import SampleApp._
import spray.json._
class SampleApp {
import MyJsonProtocol._
val inputJson = """{"children":["a", "b", "c"]}"""
println(s"Deserialise: ${inputJson.parseJson.convertTo[MyCaseClass]}")
}
object SampleApp {
case class MyCaseClass(children: List[String])
object MyJsonProtocol extends DefaultJsonProtocol {
//Explicit type added here now
implicit val myCaseClassSchemaFormat: JsonFormat[MyCaseClass] = jsonFormat1(MyCaseClass)
}
}
ワーキングコード#2 - インラインインライン、推論型:
ただし、使用される暗黙のパラメータをインラインで入力すると、なしの明示的なタイプ、また動作します!
import SampleApp._
import spray.json._
class SampleApp {
import DefaultJsonProtocol._
//Now in-line custom JsonFormat rather than imported
implicit val myCaseClassSchemaFormat = jsonFormat1(MyCaseClass)
val inputJson = """{"children":["a", "b", "c"]}"""
println(s"Deserialise: ${inputJson.parseJson.convertTo[MyCaseClass]}")
}
object SampleApp {
case class MyCaseClass(children: List[String])
}
これは、「これを行うと痛い」という質問の1つです。これは、最良の答えが「確かにそうしない」ということです。私の経験では、型の注釈を持たない暗黙的な値は、Scalaにおける混乱の最も一般的な原因の1つ、動作の奇妙なクロスバージョンの違いなどです。 –
こんにちはトラビス - 確かに、これは回避するには面白いバグでしたが、次回のタイプの注釈は私の最初の似たような問題の呼びかけになるでしょう! Scalaのバグとしてカウントされるかどうかは分かりませんが、メーリングリストに何かを載せたり、場合によっては問題を提起してください。 – MrProper
コンパイラは、 'アプリケーションポイントの後に来るため明示的な結果の型がないため、暗黙のメソッドはここには適用されません。'というエラーメッセージを出すので、少なくともエラーの診断と修正は簡単です。 – Hugh