0

我无法解决如何使此方法可重用的问题:

trait T
case class A extends T
case class B extends T

def deserialize(source:Json):A = {
  source.convertTo[A]
}

.convertTo[x]方法可以同时转换为Aand B; 但是,目前这种方法只能产生A. 调用方法时如何指定转换成什么类型​​?

澄清:

目前我可以这样做,但它是多余的,特别是当T子类的数量增加时:

def deserialize_A_(source:Json):A = {
  source.convertTo[A]
}
def deserialize_B_(source:Json):B = {
  source.convertTo[B]
}

如何将这两种方法合并为一个,以便处理所有子类T?(注意:假设嵌套方法convertTo已经可以处理所有这些子类。)

因为展示比解释更容易(我认为我写它的方式行不通):

def deserialize(source:Json, subclassToConvertTo:SubclassOfT):SubclassOfT = {
  source.convertTo[subclassToConvertTo]
}
4

2 回答 2

3

I'm not sure what library you are using, but if you look at convertTo type signature, you'll see what needs to be done. For instance, spray-json has a convertTo method that looks like this:

def convertTo[T : JsonReader]: T

The notation T : JsonReader is a context bound, a syntactic sugar for this:

def convertTo[T](implicit $ev : JsonReader[T]): T

So, basically, you need to receive a type parameter (like the T above), and an implicit value based on that type parameter, whose type depends on what convertTo on the library you are using needs. Let's say it is JsonReader, then your method becomes:

def deserialize[X : JsonReader](source:Json): X = {
  source.convertTo[X]
}

Which you need to call like this, because X cannot be inferred:

deseralize[A](someSource)

If you need X to be a subtype of T, you can add that restriction like this:

def deserialize[X <: T : JsonReader](source:Json): X = {
  source.convertTo[X]
}

PS: I'd really rather you didn't use things like T, A and B as types in your example, since they are common identifiers for type parameters.

于 2013-10-29T16:23:17.340 回答
1
def deserialize[T <: A : JsonReader](source : Json) = source.convertTo[T]

这只是根据您想要的结果类型对方法进行参数化的简单问题。任何关于 Scala 的书都应该在很早的时候介绍它。

参见例如http://twitter.github.io/scala_school/type-basics.html#parametricpoly

于 2013-10-29T16:50:57.517 回答