绑定对象的字段/方法

时间:2012-06-18 21:46:32

标签: scala generics collections existential-type type-bounds

如何使用类型绑定对象的字段/方法?

我正在尝试:

object CRUDable {

  private val allCRUDables = scala.collection.mutable.Map[String, CRUDableMeta[_]]()
  def add(crudable: CRUDableMeta[_]) { allCRUDables += (crudable.name -> crudable) }

我的编译器说:

type arguments [_$5] do not conform to trait CRUDableMeta's type parameter bounds [T <: etam.jpa.crud.CRUDable[T]]

我需要Map接受任何类型的CRUDableMeta [_]。

提前致谢,Etam。

1 个答案:

答案 0 :(得分:0)

我冒昧地构建一般案例,因为我不知道CRUD并且它没有发挥作用:

trait Data[T]
trait Meta[T <: Data[T]] { def name: String }
val all = collection.mutable.Map[String, Meta[_]]()

现在编译器会告诉你

到底出了什么问题
def add(c: Meta[_]) { all += c.name -> c }

它说:

error: type arguments [_$1] do not conform to trait
       Meta's type parameter bounds [T <: Data[T]]

因此,虽然Scala允许您构建Map而不抱怨(老实说我不知道​​为什么),但是当您尝试时,会遇到Meta的类型参数T的边界实际将值存储在地图中。

解决方案是使用以下任一形式。 (1)方法的类型参数:

def add[T <: Data[T]](c: Meta[T]) { all += c.name -> c }

(2)存在类型

def add(c: Meta[T] forSome { type T <: Data[T] }) { all += c.name -> c }

不要问我关于(2),我一直忘记存在主义类型的全部内容......也许其他人可以提供关于(1)或(2)是否更好的见解。 (the only answer to a related question表明(1)和(2)几乎相同,其中(1)还允许您随后引用类型T。虽然这里没有必要,但它仍然是更可读的版本,我会说)