在Scala中的对象成员上使用private [this]

时间:2015-05-07 00:42:47

标签: scala

在以下代码中:

object MyObj {
  private[this] def myMethod = .....
}

我对访问修饰符(私有,公共等等)的修饰符的理解是,它的存在使得它特定于该实例!在上面的例子中,我们只有一个实例。所以这不是多余的吗?

4 个答案:

答案 0 :(得分:8)

可以从类及其伴随对象访问private成员(称为class-private)。实际上无法从配对对象外部访问private[this]成员(称为对象 - 私有)。

class MyObj {
  MyObj.classPrivate
  MyObj.objectPrivate // error: symbol is not accessible
}
object MyObj {
  private def classPrivate = ???
  private[this] def objectPrivate = ???
}

简而言之,关键字在这里并不多余。

答案 1 :(得分:3)

限定符禁用访问器的生成:

scala> object X { private var v = 42 ; def x = v * 2 }
defined object X

scala> object Y { private[this] var v = 42 ; def x = v * 2 }
defined object Y

scala> :javap -pr X
Binary file X contains $line3.$read$$iw$$iw$X$
Compiled from "<console>"
public class $line3.$read$$iw$$iw$X$ {
  public static final $line3.$read$$iw$$iw$X$ MODULE$;
  private int v;
  public static {};
  private int v();
  private void v_$eq(int);
  public int x();
  public $line3.$read$$iw$$iw$X$();
}

scala> :javap -pr Y
Binary file Y contains $line4.$read$$iw$$iw$Y$
Compiled from "<console>"
public class $line4.$read$$iw$$iw$Y$ {
  public static final $line4.$read$$iw$$iw$Y$ MODULE$;
  private int v;
  public static {};
  public int x();
  public $line4.$read$$iw$$iw$Y$();
}

scala> :javap -prv X#x
  public int x();
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0       
         1: invokespecial #24                 // Method v:()I
         4: iconst_2      
         5: imul          
         6: ireturn       
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       7     0  this   L$line3/$read$$iw$$iw$X$;
      LineNumberTable:
        line 7: 0

scala> :javap -prv Y#x
  public int x();
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0       
         1: getfield      #18                 // Field v:I
         4: iconst_2      
         5: imul          
         6: ireturn       
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       7     0  this   L$line4/$read$$iw$$iw$Y$;
      LineNumberTable:
        line 7: 0

答案 2 :(得分:1)

严格地说,它不是多余的,因为它禁止来自其伴侣类的访问,该伴侣类可以访问普通的私人成员。

更重要的是,这完全不是重点。为了论证,让我们说这是多余的。是否应该仅仅因为多余而禁止private[this]对象?那将非常违反语言的设计原则!

Odersky对Scala的要求之一是摆脱任意限制,并以各种方式显示。什么东西可以嵌套声明?所有可以声明的东西:函数,特征,类和对象。而后者包装对象。什么可以嵌套在它上面?几乎所有东西(例外是包对象,因为它们也是包,而包不是成员或声明)。您在哪里可以应用可见性选项?在作为类型成员的任何声明上(因为只有类型具有成员)。等等。

总之,虽然这种特殊情况并非多余,但语言设计并不会对冗余声明表示不满。

答案 3 :(得分:0)

你在语义上是正确的,但是可能会有一些优化不适用于私有 - 没有这个(虽然它们可能是)。希望其他人可以解决优化问题。