Scala对象扩展Set实例

时间:2015-10-19 21:43:52

标签: scala scala-collections

我们知道在Scala中,可以通过在object关键字之后调用构造函数来初始化单个extends的超类的实例,如下所示:

class C(val v: Int)
object Obj extends C(1)

现在,标准库中的集合以非常特殊的方式实现,将它们的构造方法委托给伴随对象。如果我希望Obj扩展Set的某个实例怎么办?起初我天真地想写:

object Obj extends Set[Int](1, 2, 3, 4)

但是编译器抱怨道,让我想起我在这里摆出的问题。我是否误解了一些基本的Scala层次结构设计规则?

编辑:我正在揭露我的用例,以澄清为什么我觉得需要继承Set。

trait Group[A] extends Set[A] {
    def add(x: A, y: A): A
    val zero: A
    def inverse(x: A): A
}

class CyclicElement(v: Int) {
    val value = v % 4
    override def equals(x: CyclicElement) = value == x.value
}

object CyclicElement {
    def apply(v: Int) = new CyclicElement(v)
}

object CyclicGroup extends Set[CyclicElement](Zero, A, B, C) with Group[CyclicElement] {
    override def add(x: CyclicElement, y: CyclicElement) = CyclicElement(x.value + y.value)
    override val zero = CyclicElement(0)
    override def inverse(x: CyclicElement) = CyclicElement(4 - x.value)
}

1 个答案:

答案 0 :(得分:0)

编译器抱怨因为一个对象是一个单例,并且根据对象的定义,它不能在构造时获取参数。另一方面,Set是一个抽象接口,因此无论你是想创建一个对象还是一个类,都必须实现缺少的方法:

scala> class SI extends Set[Int]{}
<console>:10: error: class SI needs to be abstract, since:
it has 4 unimplemented members.
/** As seen from class SI, the missing signatures are as follows.
 *  For convenience, these are usable as stub implementations.
 */
  // Members declared in scala.collection.GenSetLike
  def iterator: Iterator[Int] = ???

  // Members declared in scala.collection.SetLike
  def -(elem: Int): scala.collection.immutable.Set[Int] = ???
  def +(elem: Int): scala.collection.immutable.Set[Int] = ???
  def contains(elem: Int): Boolean = ???

       class SI extends Set[Int]{}

然而,人们可以制作一个丑陋的解决方法:

scala> object Obj extends Set[Int] {
     | val content = Set[Int](1,2,3,4)
     | def -(elem: Int) = content-elem
     | def +(elem: Int) = content+elem
     | def contains(elem: Int) = content.contains(elem)
     | def iterator: Iterator[Int] = content.iterator
     | }
defined object Obj

scala> Obj + 5
res1: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3, 4)

(或者你可以声明content是一个可变的集合以保持更改)

更新:

解决方案是从Set:

的具体实现之一派生您的Object
scala> object Obj extends scala.collection.mutable.HashSet[Int]
defined object Obj

scala> Obj += 5
res4: Obj.type = Set(5)