2011-08-02 15 views
8

To raczej dziwne zachowanie pochodzące z REPL Scala.Obiekt towarzyszący nie może uzyskać dostępu do zmiennej prywatnej klasy

Chociaż następujących kompilacji bez problemu:

class CompanionObjectTest { 
    private val x = 3 
} 
object CompanionObjectTest { 
    def testMethod(y:CompanionObjectTest) = y.x + 3 
} 

zmienna prywatny wydaje się nie być dostępny z obiektu towarzyszącego w 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 
               ^

Dlaczego to się dzieje?

Odpowiedz

13

Co się dzieje jest to, że każdy „linia” na REPL jest właściwie umieszczony w innym opakowaniu, więc klasa i obiekt nie stają się towarzyszami. Problem ten można rozwiązać na kilka sposobów: Klasa łańcuch i obiektów definicje

Marka:

scala> class CompanionObjectTest { 
    | private val x = 3; 
    | }; object CompanionObjectTest { 
    | def testMethod(y:CompanionObjectTest) = y.x + 3 
    | } 
defined class CompanionObjectTest 
defined module CompanionObjectTest 

użyć trybu paste:

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 

umieścić wszystko wewnątrz obiektu:

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

To naprawdę trochę dziwne. Aby obejść ten problem, należy najpierw wkleić tryb wklejania z :paste, a następnie zdefiniować klasę i obiekt towarzyszący oraz zakończyć tryb wklejania za pomocą CTRL-D. Oto sesja próbka 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>