Как создать пользовательскую коллекцию, которая расширяется на Sets In Scala?

Я хочу создать новую пользовательскую коллекцию Scala из существующей коллекции наборов, которую позже я могу расширить некоторыми дополнительными функциями.

На данный момент я пытаюсь заставить его вести себя как стандартная коллекция. Я попробовал следующую ссылку: https://docs.scala-lang.org/overviews/core/custom-collections.html , где у них есть настраиваемая коллекция, которая распространяется наMap. Однако распространяясь наSetкажется немного другим, и у меня есть тонна несовместимости типов, которую я не могу решить.

Вот мой начальный код: части, которые я не могу определить,addOne,substractOne,containsиiterator.

      import scala.collection._

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

  override def empty: TestSet[A] = new TestSet

  // Members declared in scala.collection.mutable.Clearable
  override def clear(): Unit = immutable.Set.empty

  // Members declared in scala.collection.IterableOps
  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 className = "TestSet"

  //override def subtractOne(elem: A): TestSet.this.type = ???

  //override def addOne(elem: A): TestSet.this.type = ???

  //override def contains(elem: A): Boolean = ???

   //override def iterator: Iterator[A] = {
   //}
}

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
    }


}

1 ответ

Я интерпретирую ваш вопрос как «Я хочу сделать что-то похожее на пример карты из https://docs.scala-lang.org/overviews/core/custom-collections.html для изменяемого набора, но теперь я застрял с этим код» и попытается ответить на него (игнорируя любые другие аспекты вашего вопроса).

Что вам нужно понять, так это то, чтоmutable.Setиmutable.SetOps— это просто трейты, которые предоставляют некоторые повторно используемые части реализации, но они не содержат никаких реальных структур данных.

Поэтому, если вы хотите реализовать свою собственную реализацию, вам придется самостоятельно предоставить фактическую базовую структуру данных (аналогично тому, какPrefixMapпо этой ссылке естьprivate var suffixesиprivate var value).

Например, вы можете использовать базовый неизменяемый набор следующим образом:

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

  // the underlying data structure
  private var data = mutable.Set.empty[A]

  // ATTENTION: your implementation was different and buggy
  override def clear(): Unit = {
    data = mutable.Set.empty
  }

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

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

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

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

Обратите внимание, что это всего лишь пример того, что вы можете сделать, чтобы заставить ваш код работать — я не говорю, что это хорошая идея.

Другие вопросы по тегам