以下代码
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 [_]并且我认为这是问题所以我有两个问题:
更新
感谢Kim和Jean-Phillipe的回答。
我以前曾尝试过演员表,所以原来的最后一行被替换为
val responseData = resp.getEntity(classManifest[T].erasure) //Runtime error
responseData.asInstanceOf[T]
并且这个编译但是现在有一个运行时错误,因为getEntity方法传递了Object类,它无法处理,因为它需要一个更具体的类型(它有一个处理程序)。虽然它被推迟到运行时,但它再次归结为不提供特定类型信息的擦除方法,这就是为什么我认为要解决问题,必须解决内联示例。
答案 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建议的演员总是安全的。