Scala对象扩展集实例

Scala对象扩展集实例,scala,scala-collections,Scala,Scala Collections,我们知道,在Scala中,可以通过在extends关键字后调用构造函数来初始化singleton对象的超类实例,如下所示: class C(val v: Int) object Obj extends C(1) 现在,标准库中的集合是以一种非常特殊的方式实现的,将它们的构造方法委托给伴随对象。如果我想Obj扩展Set的某个实例,该怎么办?起初,我天真地想写: object Obj extends Set[Int](1, 2, 3, 4) 但编译器抱怨道,让我想到了我在这里提出的问题。我是否误

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

class C(val v: Int)
object Obj extends C(1)
现在,标准库中的集合是以一种非常特殊的方式实现的,将它们的构造方法委托给伴随对象。如果我想
Obj
扩展Set的某个实例,该怎么办?起初,我天真地想写:

object Obj extends Set[Int](1, 2, 3, 4)
但编译器抱怨道,让我想到了我在这里提出的问题。我是否误解了一些基本的Scala层次结构设计规则

编辑:我正在公开我的用例,以澄清为什么我觉得需要将集合子类化

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)
}

编译器会抱怨,因为对象是单例对象,并且根据对象的定义,无法在构造时获取参数。另一方面,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 scala.collection.mutable.HashSet[Int]
defined object Obj

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

编译器会抱怨,因为对象是单例对象,并且根据对象的定义,无法在构造时获取参数。另一方面,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 scala.collection.mutable.HashSet[Int]
defined object Obj

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

使用参数或正在构造的对象有什么意义?我想我在我发布的代码中没有看到类似的东西。除此之外,我知道这样的解决方法可能会解决问题,只是感觉不对。事实上,我要求的是一种更优雅的方式。有关答案,请参阅更新。让您的对象扩展HashSet、TreeSet或任何其他适合您的实现。然后使用不可变HashSet。但是您会收到关于不安全实现的警告。但是不允许使用
+=
!当然不是,因为您无法更改不可变集合。对象接受参数或正在构造有什么意义?我想我在我发布的代码中没有看到类似的东西。除此之外,我知道这样的解决方法可能会解决问题,只是感觉不对。事实上,我要求的是一种更优雅的方式。有关答案,请参阅更新。让您的对象扩展HashSet、TreeSet或任何其他适合您的实现。然后使用不可变HashSet。但是您会收到关于不安全实现的警告。但是不允许使用
+=
!当然不是,因为您无法更改不可变集合。1)
immutable.Set
是一种特性,因此没有构造函数。2) 一般具体的不可变实现
TreeSet
HashSet
都有私有构造函数,而且
也不推荐继承
,并带有注释
“集合的实现细节使得从它们继承不明智。”
1)不可变。Set
是一种特性,因此没有构造函数。2) 一般具体的不可变实现
TreeSet
HashSet
具有私有构造函数,并且
也不推荐继承
,并带有注释
“集合的实现细节使得从它们继承是不明智的。”