【问题标题】:Do scala constructor parameters default to private val?scala构造函数参数是否默认为私有val?
【发布时间】:2013-01-19 14:57:19
【问题描述】:

我一直在尝试:

class Foo(bar: Int)

对比:

class Foo(private val bar: Int)

虽然我找不到任何地方说(bar: Int) 扩展为(private val bar: Int),但它们的行为似乎相同,所以我的问题是,这些是 相同/相似?

附带说明,我一直在尝试在这些代码片段上使用 -Xprint:typer,它们 生成相同的代码,除了第二个中的额外行。我如何能 阅读那额外的一行?

..
class Foo extends scala.AnyRef {
  <paramaccessor> private[this] val bar: Int = _;
  def <init>(bar: Int): this.Foo = {
    Foo.super.<init>();
    ()
  }
}
..


..
class Foo extends scala.AnyRef {
  <paramaccessor> private[this] val bar: Int = _;
  <stable> <accessor> <paramaccessor> private def bar: Int = Foo.this.bar;
  def <init>(bar: Int): this.Foo = {
    Foo.super.<init>();
    ()
  }
}
..

【问题讨论】:

    标签: scala scala-primary-constructor


    【解决方案1】:

    bar: Int

    这几乎不是构造函数参数。如果除了构造函数之外没有在任何地方使用这个变量,它就会保留在那里。不生成任何字段。否则 private val bar 字段被创建,bar 参数的值被分配给它。没有创建 getter。

    private val bar: Int

    这样的参数声明将创建带有私有 getter 的 private val bar 字段。无论参数是否在构造函数旁边使用(例如在toString() 中),此行为都与上述相同。

    val bar: Int

    同上,但类似 ​​Scala 的 getter 是公开的

    bar: Int 在案例类中

    当涉及案例类时,默认情况下每个参数都有val修饰符。

    【讨论】:

    • 如果类的所有参数都将变为“公共”val
    • @om-nom-nom:对不起,我不明白。我应该改进格式/结构以使其更具可读性吗?
    • @TomaszNurkiewicz 我只是对字母大小有点脾气暴躁 ;-) 不要当真
    • @TomaszNurkiewicz: var 可用于在非casecase 类中将构造函数参数呈现到(可变)类属性中并且有意义。
    • 在“不耐烦的 Scala”一书中,bar: Int 编译为 private[this] val bar: Int
    【解决方案2】:

    在第一种情况下,bar 只是一个构造函数参数。由于主构造函数是类本身的内容,因此可以在其中访问它,但只能从这个实例中访问。所以它几乎相当于:

    class Foo(private[this] val bar:Int)
    

    另一方面,在第二种情况下,bar 是一个 普通 私有字段,因此此实例 Foo 的其他实例可以访问它。 例如,这编译得很好:

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

    然后运行:

    scala> val a = new Foo(1)
    a: Foo = Foo@7a99d0af
    
    scala> a.otherBar(new Foo(3))
    3
    

    但这不是:

    class Foo(bar: Int) {
      def otherBar(f: Foo) {
        println(f.bar) // error! cannot access bar of another foo
      }
    }
    

    【讨论】:

    • 这是一个比公认的更好的答案;它突出了裸bar: Intprivate val ... 之间的区别。
    猜你喜欢
    • 2020-08-26
    • 1970-01-01
    • 2018-11-25
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    • 1970-01-01
    • 2020-05-19
    • 1970-01-01
    相关资源
    最近更新 更多