Scala中如何定义兼容顺序与并行Vector的通用函数?
解决方案:使用
GenSeq作为通用参数类型 这个问题其实很常见,Scala集合库早就为这种“同时兼容顺序/并行集合”的场景准备了专门的抽象类型啦!
实现代码
最简洁的方式是用GenSeq作为参数类型,它是顺序序列(比如Vector)和并行序列(比如ParVector)的共同超类型,完美适配你的需求:
import scala.collection.GenSeq // 针对Int类型的简化版本,直接匹配你的示例场景 def sum1(a: GenSeq[Int]): GenSeq[Int] = a.map(_ + 1)
如果想让函数支持更多数值类型,可以结合Numeric隐式做通用化实现:
import scala.collection.GenSeq import scala.math.Numeric.Implicits._ def sum1[A: Numeric](a: GenSeq[A]): GenSeq[A] = a.map(_ + implicitly[Numeric[A]].one)
验证调用
按照你的需求测试完全没问题:
val a = (1 to 10).toVector sum1(a) // 顺序处理,返回Vector[Int] sum1(a.par) // 并行处理,返回ParVector[Int]
为什么这个方案可行?
你之前看ParVector的继承关系可能没注意到关键:ParVector继承自ParSeq,普通Vector继承自Seq,而这两个类型的共同超类型正是GenSeq。GenSeq定义了序列操作的通用接口(比如map、filter等),不管是顺序还是并行集合都实现了这些接口,所以用它作为参数类型,自然就能同时兼容两种集合。
进阶可选方案
如果你不想依赖GenSeq,也可以用结构类型约束参数必须具备map方法:
def sum1[Coll](a: Coll)(implicit ev: Coll => { def map(f: Int => Int): Coll }): Coll = a.map(_ + 1)
不过这种写法不如GenSeq直观,也失去了序列类型的语义约束,一般更推荐第一种方案。
内容的提问来源于stack exchange,提问作者Jader Martins
相关产品推荐
相关产品推荐

