如何创建具有特定类型的List的包装器

| 我正在尝试创建具有特定类型(例如
List[Int]
)的
List
包装器,以便采用隐式
CanBuildFrom
参数的方法返回我的包装器的实例而不是
List
。 一种可能感觉很沉重的解决方案是:
import scala.collection._
import generic.{CanBuildFrom, SeqForwarder}
import mutable.{Builder, ListBuffer}

class MyList(list: List[Int]) extends immutable.LinearSeq[Int]
                                 with LinearSeqLike[Int, MyList]
                                 with SeqForwarder[Int] {
  override def newBuilder: Builder[Int, MyList] = MyList.newBuilder
  protected override def underlying = list
}

object MyList {
  def newBuilder: Builder[Int, MyList] =
    new ListBuffer[Int] mapResult(new MyList(_))

  implicit def canBuildFrom: CanBuildFrom[MyList, Int, MyList] = {
    new CanBuildFrom[MyList, Int, MyList] {
      def apply(from: MyList) = from.newBuilder
      def apply() = newBuilder
    }
  }
}

val l1 = new MyList(List(1,2,3))

println(l1.isInstanceOf[MyList])
println(l1.map(_ + 1).isInstanceOf[MyList])
println(l1.filter(_ == 2).isInstanceOf[MyList])
有没有更好/更容易的方法来创建这样的包装,或者我错过了实现ѭ5的任何重要事项? 编辑:后续问题是:可以将整个包装逻辑放入
ListWrapper
类或特征中,以便可以像这样实现上述
MyList
class MyList extends ListWrapper[Int, MyList]

object MyList extends ListWrapperFactory[Int, MyList]
    
已邀请:
据阅读本文了解到: http://www.scala-lang.org/docu/files/collections-api/collections-impl.html 如果您想要filter / map / etc,则解决方案是最简单的解决方案。返回所有return5ѭ的实例。像ѭ11之类的操作需要ѭ10,而像ѭ13之类的操作则需要隐式
CanBuildFrom
,这可能会更改集合类型。 您可能会在
CanBuildFrom
中做什么:
def apply(from: MyList) = from.newBuilder // call it on `from\'
这样可以确保静态类型的“ 5”上的“ 13”实际具有动态类型,而动态类型是“ 5”的子类型,它将重用相同的动态类型。 编辑:似乎缺少一些东西,为此
map
返回
List
而不是
MyList
的实例:
val l1: LinearSeq[Int] = new MyList(List(1, 2, 3))
println(l1.map(_ + 1)) // prints List(2, 3, 4)
链接的文章中的“ 23”示例看起来也是如此。如果它具有静态类型
IndexedSeq[Base]
而不是
RNA
,则其上的
map
返回一个向量。 编辑2:看起来这是一个更普遍的问题,在此问题中进行了讨论。     
关于我的后续问题,如何通过类或特征混合包装逻辑,这是我想出的:
import scala.collection._

trait ListWrapper[Elem, Repr <: ListWrapper[Elem, Repr]]
    extends immutable.LinearSeq[Elem]
    with LinearSeqLike[Elem, Repr]
    with generic.SeqForwarder[Elem] { self: Repr =>

  def wrapperCompanion: ListWrapperCompanion[Elem, Repr]

  override def newBuilder: mutable.Builder[Elem, Repr] =
    wrapperCompanion.newBuilder
}

trait ListWrapperCompanion[Elem, Repr <: ListWrapper[Elem, Repr]] {
  def apply(elems: TraversableOnce[Elem]): Repr

  def newBuilder: mutable.Builder[Elem, Repr] =
    new mutable.ListBuffer[Elem].mapResult(apply)

  def canBuildFromWrapper: generic.CanBuildFrom[Repr, Elem, Repr] = {
    new generic.CanBuildFrom[Repr, Elem, Repr] {
      def apply(from: Repr) = from.newBuilder
      def apply() = newBuilder
    }
  }
}
现在可以通过以下方式实现“ 5”:
class MyList(val underlying: List[Int]) extends ListWrapper[Int, MyList] {
  def wrapperCompanion = MyList
}

object MyList extends ListWrapperCompanion[Int, MyList] {
  def apply(elems: TraversableOnce[Int]) = new MyList(elems.toList)

  implicit def canBuildFrom = canBuildFromWrapper
}
这绝对比在
MyList
的定义中包含所有样板代码好,但是要使
MyList
只是
List
的包装,仍然要写很多东西。     

要回复问题请先登录注册