Scala泛型类型参数问题

时间:2017-08-31 13:03:26

标签: scala generics

我对Scala相对较新,而且我遇到泛型类型参数问题。我正在为某些操作实现命令模式,我有一个像这样的基类:

abstract class Command[A, B <: BaseModel, T[X] <: CommandResponseWrapper[X] forSome { type X }](repository: BaseRepository[A, B], entity: B) {

  @throws(classOf[Exception])
  def execute: Future[T[X] forSome { type X }]
}

现在,把这个具体的命令作为我遇到的问题的一个例子:

case class AgentExecutionListCommand(repository: AgentExecutionRepository[Int, AgentExecution], entity: AgentExecution)(implicit ec: ExecutionContext) extends Command[Int, AgentExecution, AgentExecutionListResponse[Seq[AgentExecution]]](repository, entity){
  override def execute: Future[AgentExecutionListResponse[Seq[AgentExecution]]] = {
    repository.getAllMastersForAgent(entity.agentId).map(ae => AgentExecutionListResponse(ae))
  }

  override def toString: String = "Command is: AgentExecutionListCommand"
}

case class AgentExecutionListResponse[Seq[AgentExecution]](response: Seq[AgentExecution]) extends CommandResponseWrapper

存储库中的方法getAllMastersForAgent返回Future [Seq [AgentExecution]],但编译器在此行中显示错误:

repository.getAllMastersForAgent(entity.agentId).map(ae => AgentExecutionListResponse(ae))

错误是:AgentExecutionListResponse [Seq]类型的表达式不符合预期类型S _

这是什么意思?

另一个错误是:

Error:(11, 189) org.jc.dpwmanager.commands.AgentExecutionListResponse[Seq[org.jc.dpwmanager.models.AgentExecution]] takes no type parameters, expected: one
case class AgentExecutionListCommand(repository: AgentExecutionRepository[Int, AgentExecution], entity: AgentExecution)(implicit ec: ExecutionContext) extends Command[Int, AgentExecution, AgentExecutionListResponse[Seq]](repository, entity){

为什么说它不需要任何类型参数,然后又需要一个参数。我不明白。请帮忙!

提前致谢!

2 个答案:

答案 0 :(得分:1)

问题在于:

 case class AgentExecutionListResponse[Seq[AgentExecution]](response: Seq[AgentExecution]) extends CommandResponseWrapper

[...]内容应该在CommandResponseWrapper之后而不是在班级名称

之后
  case class AgentExecutionListResponse(
    response: Seq[AgentExecution]
  ) extends CommandResponseWrapper[Seq[AgentExecution]]

答案 1 :(得分:0)

对于第二个错误:

T[X] <: CommandResponseWrapper[X] forSome { type X }表示你告诉编译器T必须是一个带有单个参数的类型构造函数(这就是为什么你可以在T[X]的签名中写execute的原因,但是AgentExecutionListResponse[Seq[AgentExecution]]没有参数(你不能写AgentExecutionListResponse[Seq[AgentExecution]][SomeType])。因此,您无法将其用作T。就像您尝试拨打foo(),其中foo有参数。

另外,我认为XforSome的范围仅为CommandResponseWrapper[X] forSome { type X },因此它与T[X] <: CommandResponseWrapper[_]相同。因此,X中的T[X]命名令人困惑。

根据您对AgentExecutionListCommand#execute的期望签名,修复可能只是

abstract class Command[A, B <: BaseModel, T <: CommandResponseWrapper[_]](repository: BaseRepository[A, B], entity: B) {

  @throws(classOf[Exception])
  def execute: Future[T]
}

但这实际上取决于你想要的东西。

首先,不清楚S_来自哪里:可能来自getAllMastersForAgent的签名?在那种情况下,答案是必要的。但第二个是更基本的问题。