特征TraversableLike [A,Repr]允许一个集合,其中一些函数将返回一个Repr,而其他函数继续返回函数上的类型参数That.有没有办法定义一个CustomCollection [A],其中像map,和其他函数将默认如果没有推断,那么作为Repr?
这是一个代码片段,希望能够描述我想要的内容:
case class CustomCollection[A](list: List[A]) extends TraversableLike[A,CustomCollection[A]] { protected[this] def newBuilder = new CustomCollectionBuilder[A] def foreach[U](f: (A) => U) {list foreach f} def seq = list } class CustomCollectionBuilder[A] extends mutable.Builder[A,CustomCollection[A]] { private val list = new mutable.ListBuffer[A]() def += (elem: A): this.type = { list += elem this } def clear() {list.clear()} def result(): CustomCollection[A] = CustomCollection(list.result()) } object CustomCollection extends App { val customCollection = CustomCollection(List(1,2,3)) println(customCollection filter {x => x == 1}) // CustomCollection(1) println(customCollection map {x => x + 1}) // non-empty iterator }
我想最后一行是CustomCollection(2,3,4).
解决方法
您需要设置一个伴随对象,该对象提供精炼的CanBuildFrom实例:
import collection.TraversableLike import collection.generic.{CanBuildFrom,GenericCompanion,GenericTraversableTemplate,TraversableFactory} import collection.mutable.{Builder,ListBuffer} object CustomCollection extends TraversableFactory[CustomCollection] { def newBuilder[A] = new CustomCollectionBuilder[A] implicit def canBuildFrom[A]: CanBuildFrom[Coll,A,CustomCollection[A]] = new CanBuildFrom[Coll,CustomCollection[A]] { def apply(): Builder[A,CustomCollection[A]] = new CustomCollectionBuilder() def apply(from: Coll): Builder[A,CustomCollection[A]] = apply() } } case class CustomCollection[A](list: List[A]) extends Traversable[A] with TraversableLike[A,CustomCollection[A]] with GenericTraversableTemplate[A,CustomCollection] { override def companion: GenericCompanion[CustomCollection] = CustomCollection def foreach[U](f: A => U) { list foreach f } override def seq = list } class CustomCollectionBuilder[A] extends Builder[A,CustomCollection[A]] { private val list = new ListBuffer[A]() def += (elem: A): this.type = { list += elem this } def clear() {list.clear()} def result(): CustomCollection[A] = CustomCollection(list.result()) } val customCollection = CustomCollection(List(1,3)) val f = customCollection filter {x => x == 1} // CustomCollection[Int] val m = customCollection map {x => x + 1} // CustomCollection[Int]