2009-07-13 11 views
59

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

はたとえば、次のコードスニペット、「スカラ座でのプログラミング」からいくつかのサンプルコードの修正形を取る:

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

私の理解では、これは三つのフィールドを持つクラスを生成することである。プライベート」 g "、公開者" x "、" y "を含む。ただし、g値はxフィールドとyフィールドの計算にのみ使用され、コンストラクタスコープを超えては意味を持ちません。

この(おそらく人工的な)例では、このコンストラクタのローカル値をどのように定義しますか?

+0

他の人が私と同様の質問をしていて、私のように最初にここに来た場合のための投稿。 _constructors_と同じコンセプトを実行しようとしている場合は、私の質問に答えを使用してください:https://stackoverflow.com/questions/46455835/how-to-define-val-inside-class-constructor-in-scala –

答えて

37

など。

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

ああ、シンプル。私はまだ機能的な概念のまわりで私の直感を得ています。 – skaffman

+47

これは実際にあなたのクラスに隠されたTuple2フィールドを追加します。 –

+2

これは重要なことです。コメントありがとう、ホルヘ。 –

16

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

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

あなたははできません doは "一時的な"フィールドを宣言しています。

また、プライマリコンストラクタが受け取るパラメータはフィールドでもあることにも注意してください。このようなパラメータをフィールドにしたくない場合や、コンストラクタの実際のフィールドを公開したくない場合は、通常の解決方法はプライマリコンストラクタをプライベートにし、実際のフィールドでプライベートコンストラクタを使用するか、オブジェクトコンパニオンのapply()を有効な「プライマリ」コンストラクタとして使用します。マーティン・オーダーズキーのコメントを含めて、このトピックに関する

+0

清算していただきありがとうございます。 – skaffman

6

いくつかの議論は、我々が持っているhere

+0

それは私の質問を引き起こした本の正確な例です。私はそれが私が注意を払っていたことを意味すると思います... – skaffman

+0

スレッドが削除されました。 – ziggystar

+5

代替リンク:http://www.scala-lang.org/node/1198#comment-3430 – robinst

11

別のオプションは、プライマリオブジェクトコンストラクタをプライベートにとコンパニオンオブジェクトのビルダーのような方法を適用する使用することです。私たちはあなたの例に(しゃれが意図されていない)、このアプローチを適用する場合は、次のようになります。

val r = new R(1, 2); 

書き込み:

val r = R(1, 2); 

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インスタンスの代わりを作成するには

これは少し冗長ですが、それは悪化する可能性があります:)プライベートな[this] valが将来のScalaのリリースで一時変数として扱われることを祈りましょう。マーティン自身はそれを暗示した。

+1

最適化はScala 2.9.0.RC1ではまだ実装されていません。 – robinst

+0

robinst、Scala 2.10.2でも – MyTitle

関連する問題