我正在从这段代码片段中学习https://gist.github.com/tiqwab/bc8d372ca489a74b72dd2357e7d6b010创建一个自定义的scala Seq类。
package com.tiqwab.example.step4
import scala.collection.mutable.ListBuffer
import scala.collection.{immutable, mutable, SeqFactory, StrictOptimizedLinearSeqOps}
class MyList[+A: ClassTag] private (elems: List[A])
extends immutable.LinearSeq[A] with immutable.LinearSeqOps[A, MyList, MyList[A]]
with StrictOptimizedLinearSeqOps[A, MyList, MyList[A]] {
// To be overridden in implementations, as said in scala.collection.LinearSeq
override def isEmpty: Boolean = elems.isEmpty
override def head: A = elems.head
override def tail: MyList[A] = new MyList(elems.tail)
override def iterator: Iterator[A] = elems.iterator
// To be overridden for LinearSeqOps
override def iterableFactory: SeqFactory[MyList] = MyList
override def toString: String = s"MyList(${elems.mkString(",")})"
}
object MyList extends SeqFactory[MyList] {
override def from[A](source: IterableOnce[A]): MyList[A] =
newBuilder[A].addAll(source).result()
override def empty[A]: MyList[A] =
new MyList(List.empty)
override def newBuilder[A]: mutable.Builder[A, MyList[A]] =
new ListBuffer[A].mapResult(elems => new MyList(elems))
}
问题是如何将 ClassTag 附加到类型参数 A,如果我真的将标签附加到它,我将无法再重写 SeqFactory 中的方法。因为方法签名与 SeqFactory 中的方法签名不再一致。或者有更好的方法来使用类标签实现此类自定义集合吗?
package com.tiqwab.example.step4
import scala.collection.mutable.ListBuffer
import scala.collection.{immutable, mutable, SeqFactory, StrictOptimizedLinearSeqOps}
class MyList[+A] private (elems: List[A])
extends immutable.LinearSeq[A] with immutable.LinearSeqOps[A, MyList, MyList[A]]
with StrictOptimizedLinearSeqOps[A, MyList, MyList[A]] {
// To be overridden in implementations, as said in scala.collection.LinearSeq
override def isEmpty: Boolean = elems.isEmpty
override def head: A = elems.head
override def tail: MyList[A] = new MyList(elems.tail)
override def iterator: Iterator[A] = elems.iterator
// To be overridden for LinearSeqOps
override def iterableFactory: SeqFactory[MyList] = MyList
override def toString: String = s"MyList(${elems.mkString(",")})"
}
object MyList extends SeqFactory[MyList] {
override def from[A: ClassTag](source: IterableOnce[A]): MyList[A] =
newBuilder[A].addAll(source).result()
override def empty[A: ClassTag]: MyList[A] =
new MyList(List.empty)
override def newBuilder[A: ClassTag]: mutable.Builder[A, MyList[A]] =
new ListBuffer[A].mapResult(elems => new MyList(elems))
}
你必须修改工厂,这样它就不会是一个
object
而是一个带有构造函数的类,然后将 ClassTag
传递到那里:
class MyListFactory[A: ClassTag] {
override def from[A](source: IterableOnce[A]): MyList[A] =
newBuilder[A].addAll(source).result()
override def empty[A]: MyList[A] =
new MyList(List.empty)
override def newBuilder[A]: mutable.Builder[A, MyList[A]] =
new ListBuffer[A].mapResult(elems => new MyList(elems))
}
object MyList {
// one way of creating this things
def apply[A: ClassTag]: MyListFactory[A] = new MyListFactory[A]
// another way, requires enabling implicit conversions
implicit def convertToFactory[A: ClassTag](
notUsed: MyList.type // maybe add some @unused annotation here
): MyListFactory[A] = new MyListFactory[A]
}
SortedSet
,因为它需要Ordering[A]
。