我有一个带有混合Java-Scala代码的Lift项目。该项目有一个用Java编写的带有EclipseLink的JPA后端,由Scala端访问,后者使用Lift和Lift-NG。
在Java方面,我有以下相关接口:
interface IEntity
interface IDAO<T extends IEntity> {
void persist(T t);
}
在Scala方面,我有以下内容:
abstract class Binding[T <: IEntity] extends NgModel {
def unbind: T
}
class BasicService[B <: Binding[_ <: IEntity]](serviceName: String, dataAccessObject: IDAO[_ <: IEntity]) {
def persist(binding : B): Unit = {
val entity = binding.unbind
dataAccessObject.persist(entity)
}
}
此层次结构的目的是让我创建处理实体E的给定绑定的Service实例,它还可以接收和使用为处理类型E而创建的适当DAO。例如:
// Java side
class Todo implements IEntity
class TodoManager implements IDAO<Todo>
// Scala side
case class TodoBinding extends Binding[Todo] {
override def unbind: Todo = new Todo()
}
object HelloWorld extends BasicService[TodoBinding]("todoService", new TodoManager)
我的问题是在BasicService的persist方法中发生的编译错误。在最后一行,我明白了:
Type mismatch: expected _$1, actual: IEntity
由于我对Scala缺乏经验,我可能会遗漏一些类型系统非常明显的东西,但我真的无法弄清楚这一点。我该如何解决这个错误?
答案 0 :(得分:3)
您对BasicService
的定义不要求B
的类型参数:
B <: Binding[_ <: IEntity]
与dataAccessObject
:
dataAccessObject: IDAO[_ <: IEntity]
如果一个是Binding[FooEntity]
而另一个是IDAO[BarEntity]
怎么办?
您应该使用您说要尝试使用的类型变量E
,并实际定义它:
class BasicService[E <: IEntity, B <: Binding[E]]
(serviceName: String, dataAccessObject: IDAO[E])
另请注意,在您发布的示例代码中,可能不需要类型变量B
到BasicService
,因为您只使用它来接收参数binding
到{{1 }}。您可以在那里使用persist()
类型:
Binding[E]