我对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){
为什么说它不需要任何类型参数,然后又需要一个参数。我不明白。请帮忙!
提前致谢!
答案 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
有参数。
另外,我认为X
中forSome
的范围仅为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
的签名?在那种情况下,答案是必要的。但第二个是更基本的问题。