Scala构造函数参数的可访问性

时间:2019-05-15 05:04:56

标签: scala constructor

确定Scala构造函数参数的范围时需要澄清

根据此链接https://alvinalexander.com/scala/how-to-control-visibility-constructor-fields-scala-val-var-private#comment-13237,每当将构造函数参数标记为私有时,就不会创建getter和setter方法。但是,即使参数被标记为私有,我在此处提供的代码也可以正常工作。 我经历了这个StackOverflow链接Do scala constructor parameters default to private val?。这个与上述矛盾。有人可以解释一下。实际上,该代码段在StackOverflow链接中可用。

class Foo(private val bar: Int) {
    def otherBar(f: Foo) {
        println(f.bar) // access bar of another foo
    }
}

以下行运行正常:

val a = new Foo(1)
a.otherBar(new Foo(3))

它打印3。

按照第一个链接,由于参数是私有的,因此代码应导致编译错误。

2 个答案:

答案 0 :(得分:3)

如果您查看scala language specification,则private修饰符允许访问

  

直接包含在模板及其配套模块或配套类中。

要仅允许从实例内部进行访问,可以使用修饰符private[this]。代码

class Foo(private[this] val bar: Int) {
  def otherBar(f: Foo) {
    println(f.bar) // access bar of another foo
  }
}

产生

[error] .../src/main/scala/sandbox/Main.scala:9:17: value bar is not a member of sandbox.Foo
[error]       println(f.bar) // access bar of another foo
[error]                 ^
[error] one error found

答案 1 :(得分:3)

如果您希望仅在类内部可见的构造函数参数,请不要使其成为成员,而应将其设为普通的函数参数:

class Foo(bar: Int) {
  def otherBar(f: Foo) {
    println(f.bar) // Fails: value bar is not a member of Foo
  }
}

构造函数中的所有代码仍然可以访问bar,但是它不是Foo的成员,因此在构造函数之外不可见。