2012-06-25 24 views
7

パラメトリックフィールド(以下の例ではxなど)は通常のフィールドのように動作します。あなたが方法でそれらを参照することができます。Scalaのパラメトリックフィールドとコンストラクタ引数

class Test(val x: Int) { // x is a parametric field 
    override def toString = "Test: " + x; 
} 

をただし、あなたがキーワードvalをドロップする場合、コードはまだコンパイル(と見ていると.class出力は、xはまだクラスのメンバーです)。ですから、パラメトリックフィールド(上記のval x: Int)とコンストラクタ引数(x: Int)の違いは何ですか?

(私の頭の後ろでJavaを使用すると、私はないxのようなコンストラクタの範囲を期待しているだろうがtoStringのような方法が挙げられる。)

+0

なりなり接頭辞が 'val'であるかどうかにかかわらず、少なくとも1つのメソッドで参照されていればメンバーになります。 – adelbertc

答えて

9

valキーワードがなければ、あなたのコードは次のようにあります:class Test (private[this] val x: Int) { ... }。したがって、xはクラス全体で利用できますが、外部からは利用できません。

あなたの質問には言及されていませんが、便利かもしれません:case classのデフォルトの修飾子はvalです。したがってcase class Test(x: Int) {...}case class (val x: Int) {...}に相当します。

+2

当然のことながら、 'case class'には他のすべてのものを除いています。 :-) –

+0

@ DanielC.Sobral実際には、修正したタイプミスが実際にはタイプミスではなかったので、正確にはわかりません。 ;) – Nicolas

2

コンストラクタパラメータは実質的にprivate[this]フィールドになりますが、少なくとも1つのメソッドで参照される場合にのみ有効です。それ以外の場合、フィールドはクラス内で生成されません。例えば

class Foo(i: Int) { 
    println(i) 
} 

$ javap -private Foo 
Compiled from "Foo.scala" 
public class Foo extends java.lang.Object implements scala.ScalaObject{ 
    public Foo(int); 
} 

しかし

class Bar(i: Int) { 
    def baz = println(i) 
} 

私はX 'はまだ可能 `信じる

$ javap -private Bar 
Compiled from "Bar.scala" 
public class Bar extends java.lang.Object implements scala.ScalaObject{ 
    private final int i; 
    public void baz(); 
    public Bar(int); 
} 
関連する問題