如何创建具有特定类型的List的包装 [英] How to create a wrapper of List with a specific type
问题描述
我正在尝试创建具有特定类型(例如List[Int]
)的List
包装器,以便采用隐式CanBuildFrom
参数的方法返回我的包装器实例,而不是List
.
I am trying to create a wrapper of List
with a specific type (e.g. List[Int]
) such that methods that take an implicit CanBuildFrom
parameter return an instance of my wrapper instead of List
.
一种可能感觉很沉重的解决方案是:
One possible solution, which feels rather heavyweight, is:
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])
是否有更好/更简便的方法来创建这样的包装器,或者我错过了实现MyList
的任何重要事项?
Is there a better/easier way to create such a wrapper or did I miss anything important in the implementation of MyList
?
:一个后续问题是:是否可以将整个包装器逻辑放入ListWrapper
类或特征中,以便可以像这样实现上述MyList
:
A follow-up question is: Can this whole wrapper logic be put into ListWrapper
classes or traits so that the above MyList
can be implemented like this:
class MyList extends ListWrapper[Int, MyList]
object MyList extends ListWrapperFactory[Int, MyList]
推荐答案
据我阅读本文了解的范围:
As far I know from reading this article:
http://www.scala-lang .org/docu/files/collections-api/collections-impl.html
如果需要filter/map/etc,您的解决方案是最简单的解决方案.返回所有MyList
实例.像filter
这样的操作需要newBuilder
,而像map
这样的操作需要隐式CanBuildFrom
,这可能会更改集合类型.
your solution is the simplest one, if you want filter/map/etc. to all return instances of MyList
. newBuilder
is needed for ops like filter
, and the implicit CanBuildFrom
for ops like map
, which may change the collection type.
您可能在CanBuildFrom
中应该做的是这样:
What you should maybe do in your CanBuildFrom
is this:
def apply(from: MyList) = from.newBuilder // call it on `from'
可以确保静态类型MyList
上的map
实际上具有动态类型,而该动态类型是MyList
的子类型,
which ensures that a map
on a statically-typed MyList
which actually has a dynamic type that is a subtype of MyList
will reuse that same dynamic type.
编辑:似乎缺少一些内容,为此map
返回的是List
而不是MyList
的实例:
Edit: seems like there is a little something missing, for this map
returns an instance of List
and not MyList
:
val l1: LinearSeq[Int] = new MyList(List(1, 2, 3))
println(l1.map(_ + 1)) // prints List(2, 3, 4)
从链接的文章中获取RNA
示例的情况也是如此.如果它具有静态类型IndexedSeq[Base]
而不是RNA
,则其上的map
返回向量.
it looks like this is also the case with the RNA
example taken from the linked article. If it has static type IndexedSeq[Base]
instead of RNA
, a map
on it returns a vector.
编辑2 :看来这是一个更普遍的问题,在此问题中进行了讨论.
Edit 2: looks like this is a more general problem, discussed in this question.
这篇关于如何创建具有特定类型的List的包装的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!