【发布时间】:2016-07-02 12:57:57
【问题描述】:
抽象问题:创建一个可以混合到类的伴随对象中的特征,为该对象提供一个返回该类对象的方法。
具体问题:我正在尝试创建一组用于 RESTful 服务调用的类,它们知道如何对自身进行序列化和反序列化,如下所示:
case class Foo
(
var bar : String,
var blip : String
)
extends SerializeToJson
object Foo extends DeserializeFromJson
预期的用法是这样的:
var f = Foo( "abc","123" )
var json = f.json
var newF = Foo.fromJson( json )
我正在使用Genson 进行序列化/反序列化,我通过全局对象访问:
object JSON {
val parser = new ScalaGenson( new GensonBuilder() <...> )
}
然后我像这样定义特征:
trait SerializeToJson {
def json : String = JSON.parser.toJson(this)
}
trait DeserializeFromJson[T <: DeserializeFromJson[T]] {
def fromJson( json : String ) : T = JSON.parser.fromJson( json )
}
这编译。但这不是:
object Foo extends DeserializeFromJson[Foo]
我收到以下错误消息:
type arguments [Foo] do not conform to trait DeserializeFromJson's
type parameter bounds [T <: DeserializeFromJson[T]]
我尝试过创建单一特征,如下所示:
trait JsonSerialization[T <: JsonSerialization[T]] {
def json(implicit m: Manifest[JsonSerialization[T]]) : String =
JSON.parser.toJson(this)(m)
def fromJson( json : String ) : T =
JSON.parser.fromJson(json)
}
现在,如果我只声明case class Foo (...) extends JsonSerialization[Foo],那么我不能调用Foo.fromJson,因为只有Foo 类的实例具有该方法,而不是伴随对象。
如果我声明object Foo extend JsonSerialization[Foo],那么我可以编译并且Foo 有一个.fromJson 方法。但是在运行时,对fromJson 的调用认为T 是JsonSerialization,而不是Foo,或者以下运行时错误表明:
java.lang.ClassCastException: scala.collection.immutable.HashMap$HashTrieMap cannot be cast to ...JsonSerialization
at ...JsonSerialization$class.fromJson(DataModel.scala:14)
at ...Foo.fromJson(Foo.scala:6)
我不能声明object Foo extends Foo,因为我得到了
module extending its companion class cannot use default constructor arguments
所以我可以尝试添加构造函数参数,然后编译并运行,但再次尝试反序列化时的运行时类型是错误的,出现上述错误。
我唯一能做的就是在每个伴随对象中定义fromJson。但是必须有一种方法可以在特征中定义它,并且只需混合该特征即可。对吧?
【问题讨论】:
标签: scala generics serialization traits companion-object