2013-02-24 171 views
5

时由于需要序列化/反序列化到/从JSON以下案例类如何解决歧义的引用重载apply()方法...反序列化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

您可以选择正确的方法是这样的:因为你引用apply方法

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

编译器不能推断正确的类型。因为你明确地引用了它们,所以编译器不会为你做出这样的选择。

为了使语法更可读一点,你可以改变你的同伴对象定义

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

你可以简单地引用同伴对象,而不是模棱两可的apply方法

implicit val myClassJsonRead = (
    (__ \ 's1).read[String] ~ 
    (__ \ 's2).read[String])(MyClass) 
+0

由于这种方式,它作品:-) – j3d 2013-02-24 17:21:23