14

Scala-lang リファレンス 5.5.1 と 6.6.1 は、デフォルトのパラメーターが以前に評価されたパラメーターを参照できるという印象を与えました。

class Test(val first: String, val second: String = first)

しかし、実験から、これを行う唯一の方法は次の形式を使用することのようです:

class Test(val first: String)(val second: String = first)

次に、補助コンストラクターまたは作成コンパニオン クラスを定義して、作成時に 2 番目のブラケット セットを指定しないようにします。firstこの 2 番目のコンストラクターがどのように機能するのかよくわかりません。カリー化された関数のように見えるので、 とは独立して評価する必要があると推測できますsecondが、これは正しいですか? このフォームは必要ですか、それとも最初のコンストラクターを微調整して私がやりたいことを行うために使用できるシンタックス シュガーはありますか?

4

2 に答える 2

9

Travis Brownが指摘しているように、実際には、前の引数リストからのものである場合にのみ、デフォルト式で前の引数を参照できます (したがって、カリー化する必要があります) 。

さて、あなたの特定のユースケースに関して、デフォルトの引数とメソッドのオーバーロードは、同じことを達成するための2つの方法である場合があります。

あなたのシナリオに対する最も簡単な解決策は、単にTest次のように定義することだと思います。

class Test(val first : String, val second : String) {
  def this(f : String) = this(f, f)
}

コンパニオン オブジェクトを使用して、より複雑にしたい場合は、別の方法を使用します。

class Test(val first : String)(val second : String = first)
object Test {
  def apply(f : String) = new Test(f)
  def apply(f : String, s : String) = new Test(f)(s)
}

(小さな違いは、 を使用せずにオブジェクトを作成するようになったことnewです。)

できないことは、次のように定義することです。

class Test(val first : String)(val second : String = first) {
  def this(f : String, s : String) = this(f)(s)
}

...カリー化されたバージョンは、(とりわけ) オーバーロードされたコンストラクターと同じシグネチャを持つメソッドに変換されるためです。

于 2012-11-12T11:32:38.183 に答える
7

仕様の5.3から:

正式な値パラメーターのスコープには、後続のすべてのパラメーター セクションとテンプレートtが含まれます。

ちなみに、通常のメソッドは同じです (4.6 以降):

正式な値パラメーター名xのスコープは、後続のすべてのパラメーター句、およびメソッドの戻り値の型と関数本体 (指定されている場合) を含みます。

つまり、コンストラクターまたは通常のメソッドのどちらを持っている場合でも、値パラメーター名はそれ自体のパラメーター句のスコープ内にはありません。2 番目のバージョンでは、コンストラクターに 2 つのパラメーター句があり、2 番目のバージョンfirstでのみスコープ内にあります。複数のパラメータ句の詳細については、5.3 を参照してください。

于 2012-11-12T11:36:57.163 に答える