我可以在Scala中声明其伴随对象中的类吗?

时间:2014-12-05 17:07:18

标签: scala constructor private companion-object

在与我的私有不可变类构造函数进行斗争时,以及辅助构造函数必须作为第一个语句相互调用的约束,而没有来自类中的任何其他东西,我似乎被限制为我的实例化使用伴随对象,由于我的伴侣对象必须访问主构造函数,因此我需要使用private关键字来定位包含该对象的范围。

现在,我的大脑在名称生成方面很弱,我试图通过将我的类放在伴随对象本身中来保存对该伴随对象和类的封闭命名空间的需要,这样:

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)
//...

问题是Group的{​​{1}}没有引用该对象,但仍然是该类(使其成为多余的)。

如何将该构造函数标记为在随播对象级别可用,但不在其外部?

PS:那个伴侣对象已经给我带来了麻烦,我甚至更愿意只使用这个类,在那里加入private[Group],这可能是几个构造函数实现所需要的......

编辑:好的。就在添加标签的时候,我遇到一个神经元,让我觉得同伴对象可能对类的范围有一些特权。它可以访问它的私有部分,因此我可以简单地将对象和类放在一起而没有专用的封闭范围。但是,我仍然坚持这样一个问题:对于处理此类装箱案例范围的可能性方法的响应complexCompute以及关于在没有任何伴随对象的情况下仅在类中使用构造函数的技术的备注的机会。

2 个答案:

答案 0 :(得分: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)
}

答案 1 :(得分: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的选择更加麻烦。