scalaコンストラクターのパラメーターはデフォルトでプライベートvalですか?


128

努力しています:

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

回答:


177

bar: Int

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

private val bar: Int

このようなパラメータの宣言によりprivate val bar、プライベートゲッターを持つフィールドが作成されます。この動作は、パラメーターがコンストラクターの横で使用されているかどうかに関係なく(たとえば、内部かどうかにtoString()かかわらず)上記と同じです。

val bar: Int

上記と同じですが、Scalaのようなゲッターは公開されています

bar: Int クラスの場合

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


15
クラスの場合、すべてのパラメーターは "public"になりvalます。
drexin 2013

6
ええと、私は時々眼鏡をかけますが、これは多すぎます。
om-nom-nom 2013

1
@ om-nom-nom:すみません、わかりません。書式設定/構造を改善して読みやすくする必要がありますか?
Tomasz Nurkiewicz 2013

1
@TomaszNurkiewicz:varは、コンストラクターのパラメーターを(変更可能な)クラスプロパティに非クラスcasecaseクラスの両方でレンダリングするために使用でき、意味があります。
Randall Schulz、

8
でブック「Scalaのせっかちのために」と書いbar: Intにコンパイルprivate[this] val bar: Int
MyTitle

98

前者の場合barは、コンストラクタパラメータのみです。メインコンストラクターはクラス自体のコンテンツであるため、その中でアクセスできますが、このインスタンスからのみアクセスできます。したがって、ほぼ以下と同等です。

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

一方、2番目のケース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
  }
}

9
これは受け入れられたものよりも良い答えです。ベアbar: Intとの違いを強調していますprivate val ...
hraban 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.