2011-06-16 25 views
2

下面的代码斯卡拉ClassManifest,而不是类型的[T]

def httpPost[T: ClassManifest](data: AnyRef): T = { 
    val webResource = client.resource("http://localhost..") 
    val resp = webResource.post(classOf[ClientResponse], data) 
    resp.getEntity(classManifest[T].erasure) //Need classOf[T] here 
} 

结果基础上的答案Scala classOf for type parameter它看起来像它应该工作的这个类型不匹配的编译错误

[INFO] found : _$1 where type _$1 
[INFO] required: T 
[INFO]  resp.getEntity(classManifest[T].erasure) 

擦除方法返回java.lang.Class中的[_]和我相信,这是问题,所以我有两个问题:

  • 为什么类清单返回一个生存型,而不是简单地级[ T] - 如果它是T的删除,肯定会永远是_(下划线),因为T显然是未知的,这意味着它的返回值没有我预期的那么有用。
  • 我需要做些什么才能使代码正常工作!

更新:

感谢Kim和让 - 菲利普你的答案。

我以前试过投使原来最后一行与

val responseData = resp.getEntity(classManifest[T].erasure) //Runtime error 
responseData.asInstanceOf[T] 

取代,这个编译,但现在有一个运行时错误,因为getEntity方法传递对象的类,它不能进程,因为它需要一个更具体的类型(它有一个处理程序)。虽然它延迟到运行时,但它再次归结为擦除方法没有提供特定的类型信息,这就是为什么我认为要解决该问题,必须解决内联示例。

回答

2

这段代码有严重问题。特别是:

def httpPost[T: ClassManifest](data: AnyRef): T = { 
    val webResource = client.resource("http://localhost..") 
    val resp = webResource.post(classOf[ClientResponse], data) 
    resp.getEntity(classManifest[T].erasure) //Need classOf[T] here 
} 

斯卡拉应该怎么知道T是什么类型?你是否在调用httpPost时明确传递它?我怀疑没有,这就是为什么erasure为您返回Object的原因。

至于为什么ClassManifest#erasure回报Class[_],而不是别的东西,我怀疑的原因是,这是大多数Java方法中使用的类型,因为Class是不变的,如果erasure返回Class[T],那么你就必须将其丢用这些方法来使用它!

+0

感谢您的意见。根据我的原始更新(关于演员表),代码没有任何问题。但是,我没有在调用网站使用类型参数 - 我认为它会从分配目标中推断出来。它与那个加法一起工作。 – Dextaa 2011-06-20 09:23:57

0

第一个问题:不知道...

第二个问题:我认为在这里施放是安全的。您可以使用foo.asInstanceOf[Class[T]]

0

我相信一种存在主义类型会被返回,以表明您可能想要制作的演员是您的责任。 Class有点奇怪:例如,一个Class[List[String]]实际上应该输入为Class[List[_]],因为它不包含有关ListString参数化的任何信息。 Kim建议的演员总是安全,因为T本身不是参数化类型。