首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么不检查对象私有或对象保护定义的方差位置是安全的?

为什么不检查对象私有或对象保护定义的方差位置是安全的?
EN

Stack Overflow用户
提问于 2013-05-08 05:27:04
回答 1查看 294关注 0票数 6

我了解到Scala不会检查对象私有(private[this])或对象保护(protected[this])定义的差异位置。为什么不检查它们是安全的?

我已经阅读了一些相关的资料,但还没有找到一个完整的答案。首先,Odersky等人的"Programming in Scala“说:

http://www.artima.com/pins1ed/type-parameterization.html#19.7

事实证明,从定义变量的同一对象访问变量不会导致方差问题。直观的解释是,为了构造方差将导致类型错误的情况,您需要具有对包含对象的引用,该对象的静态类型比定义该对象时使用的类型弱。

我不确定作者所说的“包含对象”和“静态弱类型”到底是什么意思。在这里,代码示例更可取。

其次,"senia“在Scala Modifiers and Type parametrization中给出了一个很好的例子,它展示了类私有(private)字段在方差方面可能会有什么问题。这个例子让我相信为什么应该检查类私有成员的变化位置,但没有回答为什么我们不需要检查对象私有/受保护的定义。我知道像getOtherCache()这样的代码不能用对象私有字段编写。但它并没有证明对象私有/投影定义的无伤大雅,因为我们没有编写一个程序,对象私有/投影定义会导致差异问题。

第三,Michid在描述如何在Scala中实现函数memoization时简要地提到了这个主题:

http://michid.wordpress.com/2009/02/23/function_mem/

class Memoize1-T, +R extends (T => R) { ...privatethis vals = mutable.Map.emptyT,R ... }

但是,由于vals只能从其包含的实例访问,因此它不会引起方差问题。

不幸的是,它没有回答我的问题“访问控制是如何(或为什么)与差异相关的?”

您能更详细地解释不检查对象私有/受保护定义的差异位置的原因吗(或提供一些参考资料)?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-08 07:11:11

只有当对象的编译时和运行时类型不同时,才会出现方差问题:

代码语言:javascript
复制
val a: List[Any] = List("foo"): List[String]

在这里,a的静态类型(List[Any])比定义的(List[String])弱。此外,这同样适用于包含对象(即列表的元素)。(静态类型Any,定义类型String)。

如果我们有对象私有(或对象保护)字段,这种情况就不会发生:

代码语言:javascript
复制
trait A[-T] {
  protected[this] val x: T
}

当我们访问x时,我们可以确定它实际上是T类型,即使A是反向变量,因为this引用不能在某个地方向上转换。(我们总是完全了解我们的自我类型)。

所以,当我们回到奥德斯基的话,让我们来看看:

代码语言:javascript
复制
val cont: A[String] = new A[Any] { ... }
cont.x // BAD! Is `Any`, not `String`

cont是对静态类型弱于使用定义的对象的引用,这就是不允许引用x的原因。这种向上转换的情况不会发生在This指针上,因此以下内容是可以的:

代码语言:javascript
复制
trait B[-T] extends A[T] {
  def foo() {
    // here, this has always the most specific type.
    val tmp: T = this.x
    // do stuff
  }
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16428847

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档