来自Java,我正在尝试开发简单的SQL生成器,这里是这段代码的基础:
abstract class Model(val id: Long)
trait Sqlizer[A] {
def insert(model: A, ret: Boolean = false): String
}
trait Transactor {
def insert[A <: Model](row: (A, Sqlizer[A])): Transactor
def commit(): Boolean
}
object Transactor {
def apply() = new DefaultTransactor
}
class DefaultTransactor extends Transactor {
private var queries: List[(_ <: Model, Sqlizer[_ <: Model])] = List()
def insert[A <: Model](row: (A, Sqlizer[A])): Transactor = {
queries = queries :+ row
this
}
def commit(): Boolean = {
val body = queries map { kv =>
kv._2 insert kv._1
}
true
}
}
如果我没错,_ <: Model
就像Java的? extends Model
,一切都应该没问题。但是我在填写这个文件时遇到错误:
Transactor.scala:27: error: type mismatch;
found : kv._1.type (with underlying type _$1)
required: _$2
kv._2 insert kv._1
我应该如何参数化我的查询var以使其正确?或者我应该更改整个键入策略以移动Scala方式。感谢。
答案 0 :(得分:2)
这里的问题是,当你写queries: List[(_ <: Model, Sqlizer[_ <: Model])]
时,它表示该对中的第一个元素必须是扩展Model
的某种类型,而第二个元素必须是Sqlizer
类型的参数化某些类型也扩展了Model
,但并没有说这两种类型必须相同。由于类型可能不同,Sqlizer.insert
将无效,因为类型可能不兼容 - 如果Sqlizer[A].insert(param: B)
和A
都延伸{{1},则无法调用B
但是不是同一种类型。下面是一个修改版本,我将该对更改为案例类。由于case类是用单一类型参数化的,因此它的Model
方法知道它所拥有的模型和sqlizer是兼容的。
insert