我想实现一个方法,该方法接受一个元素类型的序列并返回不同元素类型的序列。我怎样才能这样做,以便返回相同的Sequence子类?
我的方法目前看起来像这样:
def lookerUpper(ids : Seq[String], someOtherInfo : Int) : Seq[UsefulData] = {
... retrieve data for each id ...
}
我希望它更通用,因此传入任何类型的(字符串)序列也是返回的(UsefulData)序列。矢量和列表,尤其是,或者我们可以做到的一般。
这可以用Scala的类型系统表达吗? “返回与此参数相同的类型,但使用不同的类型参数。”
答案 0 :(得分:3)
要获得完整的答案,你应该看看我很长的问题并回答有关构建者的问题(注意:截至2012年9月,Miles的替代版本在2.9或最新的2.10中都不起作用。)
这是一个让你入门的框架(请注意显式和隐式参数块的奇怪格式,以避免在SO上显示过长的行):
import collection.generic.CanBuildFrom
case class UsefulData(data: Int) {}
def lookerUpper[C[String]](
ids: C[String], someOtherInfo: Int
)(
implicit cbf: CanBuildFrom[C[String],UsefulData,C[UsefulData]],
ev: C[String] => Iterable[String]
): C[UsefulData] = {
val b = cbf()
val i = ev(ids)
i.foreach{ s => b += UsefulData(s.length + someOtherInfo) }
b.result
}
并观察它是否有效:
scala> lookerUpper(Vector("salmon","cod"),2)
res0: scala.collection.immutable.Vector[UsefulData] =
Vector(UsefulData(8), UsefulData(5))
scala> lookerUpper(Array("salmon","cod"),2)
res1: Array[UsefulData] =
Array(UsefulData(8), UsefulData(5))
编辑:如果您只关心TraversableLike
的子类(Array
不是),并且您将使用标准集合操作来完成所有工作,那么您可以使用{{ 3}}正如路易吉指出的那样。 (也许我应该把这个答案作为另一种观点移到那里。)