Scala中基于集合的自定义集合扩展

dced5bon  于 2023-01-09  发布在  Scala
关注(0)|答案(1)|浏览(141)

这是对以下问题的跟进:如何在Scala中创建一个扩展集的自定义集合?
我有一个在Set集合上扩展的基类,并且大多数函数(如filtercollect等)都可以正常工作:

import scala.collection._

class TestSet[A]
  extends mutable.Set[A]
    with mutable.SetOps[A, mutable.Set, TestSet[A]] {

  private var data = mutable.Set.empty[A]

  override protected def fromSpecific(coll: IterableOnce[A]): TestSet[A] = TestSet.from(coll)

  override protected def newSpecificBuilder: mutable.Builder[A, TestSet[A]] = TestSet.newBuilder

  override def empty: TestSet[A] = TestSet.empty

  override def clear(): Unit = {
    data = mutable.Set.empty
  }

  override def subtractOne(elem: A): TestSet.this.type = {
    data -= elem
    this
  }

  override def addOne(elem: A): TestSet.this.type = {
    data += elem
    this
  }

  override def contains(elem: A): Boolean = data.contains(elem)

  override def iterator: Iterator[A] = {
    data.iterator
  }

}

object TestSet {
  def empty[A] = new TestSet[A]

  def from[A](source: IterableOnce[A]): TestSet[A] =
    source match {
      case pm: TestSet[A] => pm
      case _ => (newBuilder ++= source).result()
    }

  def apply[A](elem: A*): TestSet[A] = from(elem)

  def newBuilder[A]: mutable.Builder[A, TestSet[A]] =
    new mutable.GrowableBuilder[A, TestSet[A]](empty)

  import scala.language.implicitConversions

  implicit def toFactory[A](self: this.type): Factory[A, TestSet[A]] =
    new Factory[A, TestSet[A]] {
      def fromSpecific(it: IterableOnce[A]): TestSet[A] = self.from(it)

      def newBuilder: mutable.Builder[A, TestSet[A]] = self.newBuilder
    }

}

这可能是不可能的,但我最初希望SetOps具有以下类型mutable.SetOps[A, TestSet, TestSet[A]]而不是mutable.SetOps[A, mutable.Set, TestSet[A]],但我在重新定义iterableFactory时遇到了麻烦。
可以在这里找到一个工作片段:https://scastie.scala-lang.org/4Qi8ZueDTpScDwxDfqptew

cfh9epnr

cfh9epnr1#

IterableFactory的scaladoc表示“伴随对象的基本特性......”这是一个提示,提示您的TestSet的伴随对象应该实现该特性。
你要做的就是...

object TestSet extends IterableFactory[TestSet] {
   // ...
}

...然后从配套程序中删除您的def apply[A](elem: A*): TestSet[A](因为它已经继承自IterableFactory)。
然后,您将在课堂上执行以下操作:

class TestSet[A]
  extends mutable.Set[A]
    with mutable.SetOps[A, TestSet, TestSet[A]] {

  // ...

  // returns your companion object
  override def iterableFactory: IterableFactory[TestSet] = TestSet

  // ...

}

这就是它所需要的。
(This是如此简单,因为您已经在同伴对象中实现了IterableFactory[TestSet]的所有抽象成员-如果同伴对象为空,它将无法工作。)

相关问题