努力しています:
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>();
()
}
}
..
_bar: Int
_
これはかろうじてコンストラクターパラメーターです。この変数がコンストラクター以外の場所で使用されない場合、そこに残ります。フィールドは生成されません。それ以外の場合は、_private val bar
_フィールドが作成され、bar
パラメーターの値が割り当てられます。ゲッターは作成されません。
_private val bar: Int
_
このようなパラメーターの宣言により、プライベートgetterを使用して_private val bar
_フィールドが作成されます。この動作は、パラメーターがコンストラクターの横で使用された場合(例:toString()
であるかどうかにかかわらず)と同じです。
_val bar: Int
_
上記と同じですが、Scalaのようなゲッターはパブリックです
_bar: Int
_ケースクラス
ケースクラスが関係する場合、デフォルトでは各パラメーターにval
修飾子があります。
最初のケースでは、bar
はコンストラクターパラメーターにすぎません。メインコンストラクターはクラス自体のコンテンツであるため、その中でアクセスできますが、このインスタンスからのみアクセスできます。したがって、次とほぼ同等です。
class Foo(private[this] val bar:Int)
一方、2番目の場合、bar
はnormalプライベートフィールドであるため、このインスタンスにアクセスできますおよび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
}
}