斯卡拉有界类型的地图

时间:2016-03-10 14:04:28

标签: scala generics reflection

我正在尝试在Scala中构建类似于类注册表的东西,我可以从密钥中获取类对象。 关键是我想确保我的类继承一个共同特征。

类似的东西:

trait GenericTrait{
   def doSomethingCool()
}
trait AbstractRegistry {
  def registry[T <: GenericTrait]:Map[String, Class[T]]
}

class Object1 extends GenericTrait{
   override def doSomethingCool()= println("hello")
}

class Object2 extends GenericTrait{
   override def doSomethingCool()=println("hi")
}

object MyClassRegistry extends AbstractRegistry {
  override def registry[T <: GenericTrait]:Map[String, Class[T]]=Map(
      "obj1" -> classOf[Object1],
      "obj2" -> classOf[Object2]
  )
}

但看起来我错过了一些东西,因为它没有编译...... 有什么想法吗?

1 个答案:

答案 0 :(得分:3)

A中的类[A]是invariant。这基本上意味着如果你有一个_ <: GenericTrait,你就不能输入Class [Object1]或Class [Object2]类型的地图值,因为它们是不是类[GenericTrait]的子类型。

你必须在地图的值上声明一个上部类型绑定trait GenericTrait { def doSomethingCool() } trait AbstractRegistry[T <: GenericTrait] { def registry: Map[String, Class[_ <: T]] } class Object1 extends GenericTrait { override def doSomethingCool() = println("hello") } class Object2 extends GenericTrait { override def doSomethingCool() = println("hi") } object MyClassRegistry extends AbstractRegistry[GenericTrait] { override def registry: Map[String, Class[_ <: GenericTrait]] = Map( "obj1" -> classOf[Object1], "obj2" -> classOf[Object2] ) } ,使它们成为&#34;类[T],其中T是GenericTrait的一个子类&#34; 。您还必须使T成为AbstractRegistry的类型参数而不是方法

    trait AbstractRegistry {
      def registry: Map[String, Class[_ <: GenericTrait]]
    }

正如您所评论的,如果您不需要能够将注册表子类限制为GenericTrait后代的子树,那么您真的不需要AbstractRegistry类型参数。

@using (Html.BeginForm())
    {
        @Html.RadioButton("rb_settingsupdate", "UpdateEmail"); <label>Update Email</label>
        @Html.RadioButton("rb_settingsupdate", "UpdateQuestions"); <label>Update Questions</label>
        @Html.TextBox("userpassword")
        <input type="submit" value="Submit"/>
    }