【问题标题】:Bind object's fields/methods绑定对象的字段/方法
【发布时间】:2012-06-20 22:29:34
【问题描述】:

如何将对象的字段/方法与类型绑定?

我正在努力:

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]]

我需要地图来接受任何类型的 CRUDableMeta[_]。

提前致谢,Etam。

【问题讨论】:

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


    【解决方案1】:

    我冒昧地构建一个一般案例,因为我不知道 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 而不会抱怨(老实说我不知道​​为什么),但当您尝试将值实际存储在地图。

    解决方案是使用以下任一形式。 (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。虽然这里没有必要,但它仍然是更易读的版本,我会说)

    【讨论】:

      猜你喜欢
      • 2016-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-27
      • 1970-01-01
      • 1970-01-01
      • 2014-08-04
      • 1970-01-01
      相关资源
      最近更新 更多