11

CayHorstmannの「せっかちな人のためのスカラ」からの非常に単純な演習は私を困惑させ続けます。それprimaryは、コンストラクターauxiliaryについてです:default primary

例5.10: クラスを検討する

class Employee(val name: String, var salary: Double) {
  def this() { this("John Q. Public", 0.0) }
}

明示的なフィールドとデフォルトのプライマリコンストラクターを使用するように書き直します。

やるべきことについてはよくわかりません。あなたの何人かは解決策を提案できますか?

ただし、この演習を解決しようとすると、プライマリコンストラクターとフィールドについてこれまで気づかなかったことがわかった可能性がありvalます(ご覧のとおり、よくわかりません)。

(上記のクラスのように)valフィールドはコンストラクターを介してのみ初期化でき、コンストラクターを介して初期化できないと言ったら、私は正しいですか?後者の場合、コンパイラーは、エラーの原因となるフィールドへの再割り当てと見なします。nameEmployeeprimaryauxiliaryval

val最初は、コンストラクターで初めてフィールドを割り当てることが合法であると期待して、Javaのfinalフィールドとほぼ同等のフィールドと考えていましたが、間違っていたようです。

私は大げさな推測に過ぎないかもしれないことに完全に満足していないので、誰かが私にその点についてより正確な情報を教えてくれれば幸いです。

4

2 に答える 2

14

「ProgramminginScala、第2版」の段落6.7から:

Scalaでは、すべての補助コンストラクターは、最初のアクションと同じクラスの別のコンストラクターを呼び出す必要があります。このルールの正味の効果は、Scalaでのすべてのコンストラクター呼び出しが、最終的にクラスのプライマリコンストラクターを呼び出すことになるということです。したがって、プライマリコンストラクタは、クラスの単一のエントリポイントです。

したがって、の初期化のためのすべてのデータはval、プライマリコンストラクターにある必要があります。

明示的なフィールドを持つクラスは、次のようになります。

class Employee(n: String = "John Q. Public", s: Double = 0.0) {
  val name = n
  var salary = s
}

またはデフォルトのパラメータ値なし:

class Employee(n: String, s: Double) {
  def this() = this("John Q. Public", 0.0)
  val name = n
  var salary = s
}
于 2012-05-03T07:27:22.080 に答える
12

実際、私が念頭に置いていたのは、次のような引数のないプライマリコンストラクターを備えたバージョンです。

class Employee {
  private var _name = "John Q. Public"
  var salary = 0.0
  def this(n: String, s: Double) { this(); _name = n; salary = s; }
  def name = _name      
}

明らかに、これはプライマリコンストラクターでフィールドを定義するよりも劣っています。これが私が言いたかったポイントです。

于 2012-06-12T15:27:53.920 に答える