60

Scala では、クラスのプライマリ コンストラクターに明示的な本体はありませんが、クラス本体から暗黙的に定義されます。では、フィールドとローカル値 (つまり、コンストラクター メソッドに対してローカルな値) をどのように区別するのでしょうか?

たとえば、次のコード スニペットは、"Programming in Scala" のサンプル コードを修正したものです。

class R(n: Int, d: Int) {
   private val g = myfunc
   val x = n / g
   val y = d / g
}

私の理解では、これにより、プライベート「g」、パブリック「x」および「y」の3つのフィールドを持つクラスが生成されます。ただし、g 値は x フィールドと y フィールドの計算にのみ使用され、コンストラクターのスコープ外では意味がありません。

では、この (明らかに人為的な) 例では、このコンストラクターのローカル値をどのように定義するのでしょうか?

4

4 に答える 4

37

例えば

class R(n: Int, d: Int) {
  val (x, y) = {
    val g = myfunc
    (n/g, d/g)
  }
}
于 2009-07-13T11:39:20.903 に答える
16

それにはいくつかの方法があります。このような一時変数をプライベート定義内で宣言して、構築時に使用することができます。式を返すブロック内で一時変数を使用できます(Alazの回答など)。または、最終的に、代替コンストラクター内でそのような変数を使用できます。

代替コンストラクターと同様の方法で、オブジェクト コンパニオンの「適用」メソッド内でそれらを定義することもできます。

できないことは、フィールドを「一時的」であると宣言することです。

また、プライマリ コンストラクターが受け取るパラメーターはすべてフィールドでもあることに注意してください。そのようなパラメーターをフィールドにしたくない場合、およびコンストラクターで実際のフィールドを公開したくない場合、通常の解決策は、プライマリ コンストラクターを実際のフィールドで非公開にし、代替コンストラクターまたはobject-companion の apply() を有効な「プライマリ」コンストラクタとして使用します。

于 2009-07-13T12:19:23.600 に答える
13

もう 1 つのオプションは、プライマリ オブジェクト コンストラクターをプライベートにし、コンパニオン オブジェクトの apply メソッドをビルダーとして使用することです。このアプローチをあなたの例に適用すると(しゃれは意図されていません)、次のようになります。

class R private (val x: Int, val y: Int);

object R {
  def apply(n: Int, d: Int): R = {
    val g = myfunc;
    new R(n / g, d / g);
  }
}

代わりに R インスタンスを作成するには:

val r = new R(1, 2);

書きます:

val r = R(1, 2);

これは少し冗長ですが、もっと悪いかもしれません:)。private[this] val が Scala の将来のリリースで一時変数として扱われることを期待しましょう。マーティン自身がそれをほのめかしました。

于 2010-01-28T19:46:15.353 に答える
6

Martin Odersky のコメントを含む、このトピックに関する議論はこちら

于 2009-07-13T22:44:49.957 に答える