调用方法时如何指定类型?

时间:2013-10-29 16:06:52

标签: scala types

我无法解决如何使这种方法重复使用的问题:

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

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

.convertTo[x]方法可以转化为AB;但是,目前此方法只能生成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]
}

2 个答案:

答案 0 :(得分:3)

我不确定您使用的是哪个库,但如果查看convertTo类型签名,您将看到需要执行的操作。例如,spray-json有convertTo方法,如下所示:

def convertTo[T : JsonReader]: T

符号T : JsonReader是一个上下文绑定,这是一个语法糖:

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

因此,基本上,您需要接收类型参数(如上面的T),以及基于该类型参数的隐式值,其类型取决于{{1在您正在使用的库上。假设它是convertTo,那么你的方法就变成了:

JsonReader

您需要像这样调用,因为def deserialize[X : JsonReader](source:Json): X = { source.convertTo[X] } 无法推断:

X

如果您需要deseralize[A](someSource) 成为X的子类型,则可以添加以下限制:

T

PS:我真的宁愿你没有在你的例子中使用def deserialize[X <: T : JsonReader](source:Json): X = { source.convertTo[X] } TA之类的东西,因为它们是类型参数的通用标识符。 / p>

答案 1 :(得分:1)

def deserialize[T <: A : JsonReader](source : Json) = source.convertTo[T]

这只是一个简单的问题,即根据所需的结果类型对方法进行参数化。在任何关于Scala的书中都应该很早地介绍它。

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