Scala对象扩展集实例
我们知道,在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) 但编译器抱怨道,让我想到了我在这里提出的问题。我是否误
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
具有私有构造函数,并且也不推荐继承,并带有注释“集合的实现细节使得从它们继承是不明智的。”