为什么伴生对象在编译时可以访问其伴生 class 中的私有 val,但在解释时不能这样做?
Why can a companion object access a private val in its companion class when compiling, but cannot do that when interpreting?
// Script A.scala
class A {
private val privateVal = 1
}
object A extends App{
println(new A().privateVal)
}
A.scala 可以编译并且 运行 没有问题,因为伴随对象及其 class 可以访问彼此的私有成员。
$ scalac A.scala
$ scala A
1
为什么相同的代码在解释时会显示伴随对象无法访问其伴随对象 class 中的私有 val?
$ scala A.scala
error: value privateVal in class A cannot be accessed in A
要在 Scala 中获取伴生对象,class 必须在同一个文件中定义它的伴生对象。看起来这就是您正在做的事情,尤其是当您不使用解释器时。
然而,当您在 Scala 中逐行解释代码时,它会将其包装在额外的匿名对象中,以允许在没有显式 classes 或 REPL (more here) 中的对象的情况下定义表达式。
这是包装问题的说明:
无效:
$ scala
Welcome to Scala version 2.10.6 (OpenJDK 64-Bit Server VM, Java 1.8.0_222).
Type in expressions to have them evaluated.
Type :help for more information.
scala> class A {
| private val privateVal = 1
| }
defined class A
scala> object A extends App{
| println(new A().privateVal)
| }
<console>:9: error: value privateVal in class A cannot be accessed in A
println(new A().privateVal)
^
如果同时使用 :paste
:
定义则有效
scala> :paste
// Entering paste mode (ctrl-D to finish)
// Script A.scala
class A {
private val privateVal = 1
}
object A extends App{
println(new A().privateVal)
}
// Exiting paste mode, now interpreting.
defined class A
defined module A
顺便说一句,我在 运行 scala A.scala
时没有遇到这个问题。也许我使用了不同的版本或设置。
如果您不能使用粘贴模式,或者不能让解释器一次读取整个文件,解决方法是将您的代码包装在任何对象中以强制解释单个代码块:
scala> object Workaround {
| class A {
| private val privateVal = 1
| }
| object A extends App{
| println(new A().privateVal)
| }
| }
defined module Workaround
:paste
命令也可以用于load the whole file,例如
$ scala
scala> :paste A.scala
还要考虑 ammonite,它似乎开箱即用
amm A.scala
// Script A.scala
class A {
private val privateVal = 1
}
object A extends App{
println(new A().privateVal)
}
A.scala 可以编译并且 运行 没有问题,因为伴随对象及其 class 可以访问彼此的私有成员。
$ scalac A.scala
$ scala A
1
为什么相同的代码在解释时会显示伴随对象无法访问其伴随对象 class 中的私有 val?
$ scala A.scala
error: value privateVal in class A cannot be accessed in A
要在 Scala 中获取伴生对象,class 必须在同一个文件中定义它的伴生对象。看起来这就是您正在做的事情,尤其是当您不使用解释器时。
然而,当您在 Scala 中逐行解释代码时,它会将其包装在额外的匿名对象中,以允许在没有显式 classes 或 REPL (more here) 中的对象的情况下定义表达式。
这是包装问题的说明:
无效:
$ scala
Welcome to Scala version 2.10.6 (OpenJDK 64-Bit Server VM, Java 1.8.0_222).
Type in expressions to have them evaluated.
Type :help for more information.
scala> class A {
| private val privateVal = 1
| }
defined class A
scala> object A extends App{
| println(new A().privateVal)
| }
<console>:9: error: value privateVal in class A cannot be accessed in A
println(new A().privateVal)
^
如果同时使用 :paste
:
scala> :paste
// Entering paste mode (ctrl-D to finish)
// Script A.scala
class A {
private val privateVal = 1
}
object A extends App{
println(new A().privateVal)
}
// Exiting paste mode, now interpreting.
defined class A
defined module A
顺便说一句,我在 运行 scala A.scala
时没有遇到这个问题。也许我使用了不同的版本或设置。
如果您不能使用粘贴模式,或者不能让解释器一次读取整个文件,解决方法是将您的代码包装在任何对象中以强制解释单个代码块:
scala> object Workaround {
| class A {
| private val privateVal = 1
| }
| object A extends App{
| println(new A().privateVal)
| }
| }
defined module Workaround
:paste
命令也可以用于load the whole file,例如
$ scala
scala> :paste A.scala
还要考虑 ammonite,它似乎开箱即用
amm A.scala