2011-08-02 14 views
8

Một hành vi khá lạ lùng đến từ Scala REPL.Đối tượng đồng hành không thể truy cập biến riêng tư trên lớp

Mặc dù biên dịch sau đây mà không có một vấn đề:

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

biến tin dường như không thể truy cập từ các đối tượng đồng hành trong 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 
               ^

Tại sao đó xảy ra?

Trả lời

13

Điều gì xảy ra là mỗi "dòng" trên REPL thực sự được đặt trong một gói khác, vì vậy lớp và đối tượng không trở thành bạn đồng hành. Bạn có thể giải quyết việc này trong một vài cách sau:

Make lớp chuỗi và đối tượng định nghĩa:

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

Sử dụng dán chế độ:

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 

Đặt tất cả mọi thứ bên trong một đối tượng:

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

Điều này thực sự là một chút lạ. Để giải quyết vấn đề này, bạn nên nhập chế độ dán đầu tiên với :paste, sau đó xác định lớp của bạn và đối tượng đồng hành của bạn và thoát chế độ dán bằng CTRL-D. Đây là phiên REPL mẫu:

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>