Scala ClassManifest而不是Type [T]

时间:2011-06-16 07:33:58

标签: scala

以下代码

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 
}

导致此类型不匹配编译错误

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

基于对Scala classOf for type parameter的回答,它看起来应该有效。

erasure方法返回java.lang.Class [_]并且我认为这是问题所以我有两个问题:

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

更新

感谢Kim和Jean-Phillipe的回答。

我以前曾尝试过演员表,所以原来的最后一行被替换为

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

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

3 个答案:

答案 0 :(得分: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 
}

Scala如何知道T的类型是什么?在调用httpPost时是否明确传递了它?我怀疑没有,这就是erasure为你返回Object的原因。

至于为什么ClassManifest#erasure返回Class[_]而不是其他东西,我怀疑原因是这是大多数Java方法使用的类型,因为Class是不变的,如果{ {1}}返回erasure,然后您必须将其投射以使用这些方法!

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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