【发布时间】:2017-03-07 15:03:03
【问题描述】:
对不起,令人困惑的标题。
我正在尝试编写一些 Request 和 Response 类用于验证和解析目的。我想在编译时对类型有一些保证,但仍然有运行时多态性。我有以下基类:
abstract class Response()
abstract class Request() {
type ResponseType = Response
def ResponseClass: Class[_ <: ResponseType] = classOf[ResponseType]
}
因此,如果我有一个 _ <: Request 类型的实例,我可以使用正确的类型解析,例如 JSON 响应:Json.parse(responseString).as[request.ResponseType]。
我发现当我扩展这些类时,我无法override ResponseType:
case class AddedFooResponse() extends Response
case class AddFooRequest() extends Request {
override type ResponseType = AddedFooResponse
}
错误:覆盖类
Request中的类型ResponseType,等于this.Response; 类型ResponseType具有不兼容的类型override type ResponseType = AddedFooResponse
我不确定为什么这些类型不兼容。我目前的解决方法有点笨拙,就是在基类中绑定类型:
abstract class Response()
abstract class Request() {
type ResponseType <: Response
// cannot initialize because no concrete class
def ResponseClass: Class[_ <: ResponseType]
}
并简单地覆盖ResponseType 和ResponseClass:
case class AddedFooResponse() extends Response
case class AddFooRequest() extends Request {
override type ResponseType = AddedFooResponse
override def ResponseClass = classOf[ResponseType]
}
这需要大量(看似)不必要的样板来覆盖ResponseClass。
我做错了什么?
【问题讨论】:
-
为什么要这样存储
ResponseType的类呢?我觉得可能有更好的方法来实现您所需要的,而不需要java.lang.Class。 -
@MichaelZajac 我有一个验证器,它将
ResponseClass与收到的Response的类进行比较。如果我有响应类型,它可能会变得没有意义。如果不出意外,这个问题很有趣。充其量是实用的。如果您有兴趣,请参阅here。 -
我会说使用
type ResponseType <: Response是朝着正确方向迈出的一步,但是使用classOf并不能很好地工作,这就是为什么它需要退出摘要班级。否则你有一个不变的类型成员。 -
@MichaelZajac 那么你知道我如何能够实现
request.ResponseType == typeOf[response]这样的目标吗?也许这就是问题的症结所在。
标签: scala oop generics type-members