web-dev-qa-db-ja.com

scalaコンストラクタパラメータはデフォルトでprivate valになりますか?

努力しています:

class Foo(bar: Int)

対:

class Foo(private val bar: Int)

(bar: Int)(private val bar: Int)に展開するということをどこにも見つけることができませんでしたが、彼らは同じように動作するようです。

補足として、私はこれらのコード部分で-Xprint:typerを使用しようとしており、2番目の行の余分な行を除いて同じコードを生成します。余分な行をどのように読みますか?

..
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>();
    ()
  }
}
..
118
none

_bar: Int_

これはかろうじてコンストラクターパラメーターです。この変数がコンストラクター以外の場所で使用されない場合、そこに残ります。フィールドは生成されません。それ以外の場合は、_private val bar_フィールドが作成され、barパラメーターの値が割り当てられます。ゲッターは作成されません。

_private val bar: Int_

このようなパラメーターの宣言により、プライベートgetterを使用して_private val bar_フィールドが作成されます。この動作は、パラメーターがコンストラクターの横で使用された場合(例:toString()であるかどうかにかかわらず)と同じです。

_val bar: Int_

上記と同じですが、Scalaのようなゲッターはパブリックです

_bar: Int_ケースクラス

ケースクラスが関係する場合、デフォルトでは各パラメーターにval修飾子があります。

167

最初のケースでは、barはコンストラクターパラメーターにすぎません。メインコンストラクターはクラス自体のコンテンツであるため、その中でアクセスできますが、このインスタンスからのみアクセスできます。したがって、次とほぼ同等です。

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

一方、2番目の場合、barnormalプライベートフィールドであるため、このインスタンスにアクセスできますおよび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
  }
}
88
gourlaysama