1

プライベートな不変クラス コンストラクターと、補助コンストラクターが最初のステートメントとして相互に呼び出さなければならないという制約と戦っている間、スコープ内のクラスから他に何もないため、インスタンス化にコンパニオン オブジェクトを使用するように制約されているようです。コンパニオン オブジェクトはメイン コンストラクターにアクセスする必要があります。そのオブジェクトを含むスコープを対象とするプライベート キーワードが必要です。

さて、私の脳は名前生成に弱いので、次のようにクラスをコンパニオン オブジェクト自体の中に配置することで、そのコンパニオン オブジェクトとクラスの両方を囲む名前空間の必要性を救おうとしています。

object Group {
  private def complexComputeX(z: Int) = z
  private def complexComputeY(x: Int, z: Int) = x + z
  def apply(z: Int) = {
    val x = complexComputeX(z)
    val y = complexComputeY(x, z)
    new Group(x, y)
  }
  class Group private[Group](x: Int, y: Int) {
    //...
  }
}
val x = Group(5)
//...

問題は、Groupofprivate[Group]がオブジェクトを参照するのではなく、クラスを参照することです (余計なものになっています)。

そのコンストラクターをコンパニオン オブジェクト レベルで使用できるようにタグ付けするにはどうすればよいですか?

PS:そのコンパニオンオブジェクトはすでに私に頭痛の種を与えておりcomplexCompute、いくつかのコンストラクターの実装が必要になる可能性のあるクラスをエンスコープすることさえ望んでいたでしょう...

編集:わかりました。タグを追加しているときに、コンパニオン オブジェクトがクラスのスコープに対してなんらかの権限を持っている可能性があることを知らせるニューロンにぶつかりました。プライベート パーツにアクセスできるため、専用の囲みスコープなしでオブジェクトとクラスを並べて配置できます。object Main {object Main {object Main...ただし、このようなボクシング ケースのスコーピングを処理する可能性のある方法についての回答と、コンパニオン オブジェクトを使用せずにクラスにコンストラクターのみを含める手法についての発言の可能性の両方について、質問を維持します。

4

2 に答える 2

3

同じ名前空間にないため、 Group オブジェクトは Group クラスのコンパニオン オブジェクトではありません。

private修飾子にスコープを提供する必要はありません。空のままにすると、このクラスとそのコンパニオン オブジェクトのみがアクセスできます。

object Something {

  class Group private(x: Int, y: Int)
  object Group {
    private def complexComputeX(z: Int) = z
    private def complexComputeY(x: Int, z: Int) = x + z
    def apply(z: Int) = {
      val x = complexComputeX(z)
      val y = complexComputeY(x, z)
      new Group(x, y)
    }
  }
  val x = Group(5)

  // This line doesn't compile
  new Group(42, 45)
}
于 2014-12-05T19:29:56.083 に答える
0

コンパニオン オブジェクトのプライベートにもクラスからアクセスできるため、根本的な問題に関して、次のような別のオプションがあります。

object Group {
  private def computeX(z: Int) = z
  private def computeY(x: Int, z: Int) = x + z
  private def computeXY(z: Int) = {
    val x = computeX(z)
    (x, computeY(x, z))
  }
}
class Group private (x: Int, y: Int) {
  private def this(xy: (Int, Int)) = this(xy._1, xy._2)
  def this(z: Int) = this(Group.computeXY(z))
}
val group = new Group(5)

コンパニオン オブジェクトによって、完全にプライベートなスコープがコンストラクターから利用できるようになると、息が詰まります。私の完全なケースでは、プライベートにしたいタイプも必要でした。このローカルで有用なスコープを含むコンパニオンを作成する必要があるという事実は、今ではそれほど重要ではないかもしれません。ただし、タプルを使用すると、Dimitri のオプションよりも扱いにくくなります。

于 2014-12-05T22:24:36.190 に答える