首页 文章

混淆scala私有字段变量

提问于
浏览
4

我是斯卡拉研究的第三天 . 使用书“开始scala” .

作者使用一个例子来显示变量define与val var之间的差异而没有var val:

class Book(private val title: String) {
   def printTitle(b: Book) {
       println(b.title)
   }
}

在控制台中:

scala> val book = new Book("Beginning Scala")
book: Book = Book@ea05be
scala> book.printTitle(new Book("Beginning Erlang"))
Beginning Erlang

这里让我感到困惑的是没有/没有val var,而是私有修饰符:

我不确定我是否理解私权,但如果scala想要 title as private field ,那么 why it allows others to access it from outside ,我认为prinTitle应该无法访问新书("Beginning Erlang")的 Headers 字段

2 回答

  • 8

    title 对于类是私有的,而不是对实例的私有 . 由于方法 printTitle 是类的成员,因此它可以访问其他实例的私有值 .

    如果您希望 title 是实例的私有,则可以使用 private[this] 修饰符 .

    此外, private[package] 修饰符,其中 package 是定义所在的包的名称,可以与包共享私有成员 . 例如

    package com.sample.foo
    
    class Book(private[foo] title: String)
    

    可以访问包中的所有代码 com.sample.foo

  • 3

    title 是类 Book 的私有字段 .

    在Java中你写的像:

    class Book {
        private final String title;
    
        Book(String title) {
            this.title = title;
        }
    
        public void printTitle(b: Book) {
           System.out.println(b.title)
        }
     }
    

    我认为函数 printTitle 可能有点令人困惑,因为在java和scala中它通常不会被实现为实例方法 . 我会写这样的东西作为java中的静态方法 . 在scala我会把它放入一个伴侣对象(在一个混乱的scala newby中抛出另一个外星人的概念;)):

    class Book(private val title: String)
    
    object Book {
        def printTitle(b: Book) {
           println(b.title)
       }
    }
    

    因此,Book可以访问任何Book实例的任何私有字段 .

    如果您想限制对Book实例的 Headers 访问,您可以编写如下内容:

    class Book(private[this] val title: String) {
       // no longer compiles
       // def printTitle(b: Book) {
       //    println(b.title)
       //}
    
       def printTitle() {
           println(title)
       }
    }
    

相关问题