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

时间:2023-01-15 15:17:31

In the following code:

在以下代码中:

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

My understanding of the this modifier to the access modifiers (private, public... etc.,) is that the presence of this makes it specific to that instance! In the case above we only have one instance. So isn't this redundant?

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

4 个解决方案

#1


The qualifier disables generation of accessors:

限定符禁用生成访问器:

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


A private member (which is called class-private) is accessible from both the class and its companion object. A private[this] member (called object-private) is truly not accessible from outside the companion object.

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

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

So in short, the keyword is not redundant here.

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

#3


Strictly speaking, it isn't redundant because it forbids access from its companion class, which can access normal private members.

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

More importantly, that's completely besides the point. For the sake of the argument, let's say it is redundant. Should private[this] be forbidden on objects just because it is redundant? That would be very much against the design principles of the language!

更重要的是,这完全不是重点。为了论证,让我们说这是多余的。私有[this]是否应该被禁止在对象上,因为它是多余的?这将非常违背语言的设计原则!

One of the things Odersky wanted for Scala is to get rid of arbitrary restrictions, and that shows in all sorts of ways. What things can have nested declarations? Everything that can have declarations: functions, traits, classes and objects. And, latter, package objects. What can be nested on it? Again, almost everything (the exception being package objects, because they are also packages, and packages are not members or declarations). Where can you apply visibility options? On any declaration that is a member of a type (because only types have members). And so on.

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

In summary, while this particular case is not redundant, the language design doesn't frown on redundant declarations.

总之,虽然这种特殊情况并非多余,但语言设计并不会对冗余声明产生任何影响。

#4


You're right, semantically, but there might be some optimizations that aren't applied for private-without-this (though they probably could be). Hopefully someone else can nail the optimization question down.

从语义上讲,你是对的,但是可能会有一些优化没有应用于私有 - 没有这个(尽管它们可能是)。希望其他人可以解决优化问题。

#1


The qualifier disables generation of accessors:

限定符禁用生成访问器:

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


A private member (which is called class-private) is accessible from both the class and its companion object. A private[this] member (called object-private) is truly not accessible from outside the companion object.

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

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

So in short, the keyword is not redundant here.

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

#3


Strictly speaking, it isn't redundant because it forbids access from its companion class, which can access normal private members.

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

More importantly, that's completely besides the point. For the sake of the argument, let's say it is redundant. Should private[this] be forbidden on objects just because it is redundant? That would be very much against the design principles of the language!

更重要的是,这完全不是重点。为了论证,让我们说这是多余的。私有[this]是否应该被禁止在对象上,因为它是多余的?这将非常违背语言的设计原则!

One of the things Odersky wanted for Scala is to get rid of arbitrary restrictions, and that shows in all sorts of ways. What things can have nested declarations? Everything that can have declarations: functions, traits, classes and objects. And, latter, package objects. What can be nested on it? Again, almost everything (the exception being package objects, because they are also packages, and packages are not members or declarations). Where can you apply visibility options? On any declaration that is a member of a type (because only types have members). And so on.

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

In summary, while this particular case is not redundant, the language design doesn't frown on redundant declarations.

总之,虽然这种特殊情况并非多余,但语言设计并不会对冗余声明产生任何影响。

#4


You're right, semantically, but there might be some optimizations that aren't applied for private-without-this (though they probably could be). Hopefully someone else can nail the optimization question down.

从语义上讲,你是对的,但是可能会有一些优化没有应用于私有 - 没有这个(尽管它们可能是)。希望其他人可以解决优化问题。