dki*_*kim 5 scala covariance contravariance
我了解到Scala不会检查object-private(private[this])或object-protected(protected[this])定义的方差位置.为什么不检查它们是否安全?
我已经阅读了一些与之相关的材料,但未能找到完整的答案.首先,Odersky等人的"Scala编程"说:
http://www.artima.com/pins1ed/type-parameterization.html#19.7
事实证明,从定义它们的同一对象访问变量不会导致方差问题.直观的解释是,为了构造方差会导致类型错误的情况,您需要引用一个包含对象,该对象具有比定义对象的类型更静态的类型.
我不确定作者的意思是" 包含对象"和" 静态较弱的类型".这里更优选代码示例.
其次,"senia"在Scala Modifiers和Type参数化中给出了一个很好的例子,它显示了class-private(private)字段可能带有方差的问题.这个例子让我相信为什么应该检查类私有成员的差异位置,但是没有给出我们不必检查对象私有/受保护定义的原因的答案.我理解这样的代码getOtherCache()不能用object-private字段写.但它没有给出对象私有/预测定义无害的证据,我们没有编写一个程序,对象 - 私有/预测定义导致方差问题.
第三,在解决如何在Scala中实现函数memoization时,Michid简要地提到了这个主题:
http://michid.wordpress.com/2009/02/23/function_mem/
Run Code Online (Sandbox Code Playgroud)class Memoize1[-T, +R](f: T => R) extends (T => R) { ... private[this] val vals = mutable.Map.empty[T, R] ... }但是,由于仅从包含实例访问val,因此不会导致方差问题.
不幸的是,它没有回答我的问题"如何(或为什么)是与方差相关的访问控制?".
您能否更详细地解释不检查对象 - 私有/受保护定义的方差位置(或提供一些参考)的基本原理?
只有在对象的编译时和运行时类型不同时才会出现方差问题:
val a: List[Any] = List("foo"): List[String]
Run Code Online (Sandbox Code Playgroud)
这里a有一个静态较弱的类型(List[Any])而不是定义的(List[String]).此外,这同样适用于包含对象(即列表的元素).(静态类型Any,定义类型String).
如果我们有对象私有(或受对象保护)字段,则不会发生这种情况:
trait A[-T] {
protected[this] val x: T
}
Run Code Online (Sandbox Code Playgroud)
当我们访问时,x我们可以确定它实际上是类型T,即使A是反式变体,因为this引用不能在某处向上转换.(我们总是完全了解自己的自我类型).
所以当我们回到奥德斯基的话时,让我们来看看:
val cont: A[String] = new A[Any] { ... }
cont.x // BAD! Is `Any`, not `String`
Run Code Online (Sandbox Code Playgroud)
cont是对具有静态弱于定义的对象的引用,这x就是不允许引用的原因.使用this指针不会发生这种上转情况,因此以下情况可以:
trait B[-T] extends A[T] {
def foo() {
// here, this has always the most specific type.
val tmp: T = this.x
// do stuff
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
268 次 |
| 最近记录: |