1. ホーム
  2. scala

[解決済み] scala のコンストラクタのパラメータはデフォルトで private val になりますか?

2022-06-23 11:25:39

質問

試行錯誤しています。

class Foo(bar: Int)

vs:

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

どのように解決するのですか?

bar: Int

これはほとんどコンストラクタのパラメータではありません。この変数がコンストラクタ以外の場所で使用されない場合、そのまま残ります。フィールドは生成されません。そうでなければ private val bar フィールドが作成され bar パラメータの値が代入される。ゲッターは作成されません。

private val bar: Int

このようなパラメータの宣言は private val bar フィールドが作成されます。この挙動は、パラメータがコンストラクタの横で使われたとしても (例えば toString() の中で)使用されたかどうかに関係なく、この動作は上記と同じです。

val bar: Int

上記と同じですが、Scalaのようなゲッターはpublicです。

bar: Int の場合、クラスは

ケースクラスが含まれる場合、デフォルトでは各パラメータに val 修飾子を持ちます。