Почему объект-компаньон может получить доступ к закрытому значению val в своем классе-компаньоне при компиляции, но не может этого сделать при интерпретации? - PullRequest
1 голос
/ 24 октября 2019
// 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 ]

6 голосов
/ 24 октября 2019

Чтобы получить объект-компаньон в Scala, класс и его объект-компаньон должны быть определены в одном файле. Похоже, это то, что вы делаете, особенно когда вы не используете переводчик.

Однако, когда вы интерпретируете код построчно в Scala, он оборачивает его в дополнительный анонимный объект, чтобы выражения могли быть определены без явных классов или объектов в REPL ( подробнее здесь ).

Вот иллюстрация проблемы обтекания:

Не работает:

$ 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
3 голосов
/ 24 октября 2019
Команда

:paste также может быть использована для загрузки всего файла , например,

$ scala
scala> :paste A.scala

Также рассмотрим аммонит , который, кажется, работаетof-the-box

amm A.scala
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...