Объект Companion не может получить доступ к закрытой переменной класса
Скорее странное поведение, исходящее из Scala REPL.
Хотя следующие компиляции без проблем:
class CompanionObjectTest {
private val x = 3
}
object CompanionObjectTest {
def testMethod(y:CompanionObjectTest) = y.x + 3
}
приватная переменная не представляется доступной из объекта-компаньона в REPL:
scala> class CompanionObjectTest {
|
| private val x = 3;
| }
defined class CompanionObjectTest
scala> object CompanionObjectTest {
|
| def testMethod(y:CompanionObjectTest) = y.x + 3
| }
<console>:9: error: value x in class CompanionObjectTest cannot be accessed in CompanionObjectTest
def testMethod(y:CompanionObjectTest) = y.x + 3
^
Почему это происходит?
Ответы
Ответ 1
Что происходит, так это то, что каждая "строка" на REPL фактически помещается в другой пакет, поэтому класс и объект не становятся компаньонами. Вы можете решить это несколькими способами:
Сделать определения класса и объектов цепи:
scala> class CompanionObjectTest {
| private val x = 3;
| }; object CompanionObjectTest {
| def testMethod(y:CompanionObjectTest) = y.x + 3
| }
defined class CompanionObjectTest
defined module CompanionObjectTest
Использовать режим вставки:
scala> :paste
// Entering paste mode (ctrl-D to finish)
class CompanionObjectTest {
private val x = 3
}
object CompanionObjectTest {
def testMethod(y:CompanionObjectTest) = y.x + 3
}
// Exiting paste mode, now interpreting.
defined class CompanionObjectTest
defined module CompanionObjectTest
Поместите все внутри объекта:
scala> object T {
| class CompanionObjectTest {
| private val x = 3
| }
| object CompanionObjectTest {
| def testMethod(y:CompanionObjectTest) = y.x + 3
| }
| }
defined module T
scala> import T._
import T._
Ответ 2
Это действительно немного странно. Чтобы обойти эту проблему, вы должны сначала ввести режим вставки с помощью :paste
, а затем определить свой класс и свой сопутствующий объект и выйти из режима вставки с помощью CTRL-D. Вот пример сеанса REPL:
Welcome to Scala version 2.9.0.1 (OpenJDK Server VM, Java 1.6.0_22).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :paste
// Entering paste mode (ctrl-D to finish)
class A { private val x = 0 }
object A { def foo = (new A).x }
// Exiting paste mode, now interpreting.
defined class A
defined module A
scala>