pr1*_*001 3 types scala 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
}
}
Run Code Online (Sandbox Code Playgroud)
我试图让我的类可以使用子类,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
^
Run Code Online (Sandbox Code Playgroud)
问题是,我认为,我定义的方式(以及何时?)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
}
Run Code Online (Sandbox Code Playgroud)
如何声明一个librariesHashMap,使其具有Library不同Services的多个s?是否可以参考Service这里或不可能?
还是我完全吠叫错了树?谢谢!
在Scala的参数化类型,默认情况下不变的,例如,对于Cage[A]一个Cage[Bird]是不是一个Cage[Animal].但是你可以通过方差声明来制作类型协变甚至逆变,例如Cage[+A](a: A),这就是编译器试图在错误消息中告诉你的内容.
现在,并不总是可以使类型参数协变.这仅在类型变量仅用于所谓的正面事件时才有效.如果你的类是不可变的,那么换一种方法(不是100%正确).在你的情况下,它会工作.所以你要做的就是添加一个+定义Library:
class Library[+T <: Service](collection: Collection[T], actives: Actives[T])
Run Code Online (Sandbox Code Playgroud)
正如编译错误所说,类Library是不变的。那是:
Library[S] <: Library[T]当且仅当S <: T
不成立。此属性称为协方差,是泛型类型参数的属性。这导致编译器错误的原因是您的 Map 期望Library[Service]作为其值类型,并且您正在尝试添加 a Library[T](由于缺乏协方差,它不是 a Library[Service],即使T <: Service)
如果您的Library类是不可变的,那么您应该能够+向类型参数添加 a 以指示scalacLibrary的类型是协变的。
| 归档时间: |
|
| 查看次数: |
3948 次 |
| 最近记录: |