5

JSONとの間でシリアル化/逆シリアル化する必要がある次のケースクラスを考えると...

import play.api.libs.json
import play.api.libs.functional.syntax._

trait MyTrait(s1: String, s2: String)

case class MyClass(s1: String, s2: String) extends MyTrait {

  def this(t: MyTrait) = this(t.s1, t.s2)
}

object MyClass {

  def apply(t: MyTrait) = new MyClass(t)

  implicit val myClassJsonWrite = new Writes[MyClass] {
    def writes(c: MyClass): JsValue = {
      Json.obj(
        "s1" -> c.s1,
        "s2" -> c.s2
      )
    }
  }

  implicit val myClassJsonRead = (
    (__ \ 's1).read[String] ~
    (__ \ 's2).read[String]
  )(MyClass.apply _)
}

...次のエラーメッセージが常に表示されます。

[error] /home/j3d/Projects/test/app/models/MyClass.scala:52: ambiguous reference to overloaded definition,
[error] both method apply in object MyClass of type (s1: String, s2: String)models.MyClass
[error] and  method apply in object MyClass of type (t: MyTrait)models.MyClass
[error] match expected type ?
[error]   )(MyClass.apply _)
[error]             ^

apply... コンパイラが正しいメソッドを推論しないのはなぜですか? このエラーを修正するにはどうすればよいですか? どんな助けでも本当に感謝しています。ありがとう。

4

1 に答える 1

5

次のように正しい方法を選択できます。

MyClass.apply(_: String, _: String)

メソッドを参照しているため、コンパイラは正しい型を推測できませんapply。それらを明示的に参照するため、コンパイラはその選択を行いません。

構文をもう少し読みやすくするために、コンパニオン オブジェクトの定義を変更できます。

object MyClass extends ((String, String) => MyClass) {

applyそうすれば、あいまいなメソッドの代わりにコンパニオン オブジェクトを簡単に参照できます。

implicit val myClassJsonRead = (
  (__ \ 's1).read[String] ~
  (__ \ 's2).read[String])(MyClass)
于 2013-02-24T15:21:38.290 に答える