为什么在编译时,伴侣对象可以在其伴侣类中访问私有val,而在解释时却不能这样做?

时间:2019-10-24 08:50:09

标签: scala read-eval-print-loop companion-object

// Script A.scala
class A {
    private val privateVal = 1
}
object A extends App{ 
    println(new A().privateVal)
}

A.scala可以毫无问题地进行编译和运行,因为同伴对象及其类可以访问彼此的私有成员。

$ scalac A.scala
$ scala A
1

为什么相同的代码在解释时会显示伴随对象无法访问其伴随类中的私有val?

$ scala A.scala
error: value privateVal in class A cannot be accessed in A

2 个答案:

答案 0 :(得分:6)

要在Scala中获得伴侣对象,必须在同一文件中定义一个类及其伴侣对象。看起来这就是您正在执行的操作,尤其是当您不使用解释器时。

但是,当您在Scala中逐行解释代码时,会将其包装在其他匿名对象中,以允许在没有显式类或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

答案 1 :(得分:3)

例如,

:paste命令也可用于load the whole file

$ scala
scala> :paste A.scala

还要考虑ammonite,它似乎是开箱即用的

amm A.scala
相关问题