Scala 上类型边界和父类

标签 scala types type-bounds

我真的很喜欢使用类型上限来为我的结构提供一些灵活性。但是,我真的不知道它背后的任何原则,因为我发现以下代码:

object BoundsTest {
  abstract trait Service
  class Collection[T <: Service] extends collection.mutable.HashMap[Symbol, collection.mutable.Set[T]] with collection.mutable.MultiMap[Symbol, T]
  type Actives[T <: Service] = collection.mutable.HashMap[Symbol, T]
  class Library[T <: Service](collection: Collection[T], actives: Actives[T])
  private val libraries = new collection.mutable.HashMap[Symbol, Library[Service]]
  def setLibrary[T <: Service](name: Symbol, library: Library[T]) {
    libraries += name -> library
  }
}

我试图让我的类(class)可以使用 Service 的子类只要它是一致的。但是,这不起作用:
$ scalac test.scala 
test.scala:10: error: type mismatch;
 found   : com.bubblefoundry.BoundsTest.Library[T]
 required: com.bubblefoundry.BoundsTest.Library[com.bubblefoundry.BoundsTest.Service]
Note: T <: com.bubblefoundry.BoundsTest.Service, but class Library is invariant in type T.
You may wish to define T as +T instead. (SLS 4.5)
    libraries += name -> library
                         ^

我认为问题在于我如何(以及何时?)定义 libraries ,好像我做了以下更改,一切都编译成功:
// private val libraries = new collection.mutable.HashMap[Symbol, Library[Service]]
def setLibrary[T <: Service](name: Symbol, library: Library[T]) {
  new collection.mutable.HashMap[Symbol, Library[T]] += name -> library
}

我如何申报 libraries HashMap 使得它有多个 Library s 不同 Service ?可以引用Service在这里还是不可能?

还是我完全在错误的树上吠叫?谢谢!

最佳答案

在 Scala 中,参数化类型默认是不变的,例如为 Cage[A] Cage[Bird]不是 Cage[Animal] .但是您可以通过方差声明来使类型协变甚至逆变,例如Cage[+A](a: A) ,这就是编译器试图在错误消息中告诉您的内容。

现在并不总是可以使类型参数协变。这仅在类型变量仅用于所谓的正发生时才有效。或者换一种方式(不是 100% 正确),如果你的类是不可变的。在你的情况下,它会起作用。所以你所要做的就是添加一个 +Library的定义:

class Library[+T <: Service](collection: Collection[T], actives: Actives[T])

关于Scala 上类型边界和父类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7399044/

相关文章:

oracle - 多次插入类型表集合

java - 如何在 Java 泛型中返回类对象 "type"?

scala - 强制下限 "excludes"父类(super class)型

java - 类型边界 : Propagate parameter with multiple bounds

eclipse - 如何使用Scala Eclipse IDE连接到现有的Hive

java - Scala:字符串 "+"与 "++"

scala - Spark 比较 bool 列与字符串列的工作方式与比较 int 和字符串(其中值相等)的方式不同

javascript - HTML 元素数组的类型错误

scala - 如果 bound 是抽象类型成员,则具有上限的更高种类的类型构造函数不起作用

scala - 展平 Future[Option[Option[T]]] 的 Option 部分