我正在实现一个通用算法来返回一个基于其他两个集合的集合。问题可以简化为
def add[Repr <: Traversable[_]](coll1: Repr, coll2: Repr) = coll1 ++ coll2
当我将算法应用于我定义为的集合 A 时出现问题
class A[T] extends Iterable[(Int,T)] with IterableLike[(Int,T), A[T]] { ... }
即,A 的类型参数与继承的 Iterable 不同。Map 使用了类似的方法。
地图示例:
scala> val m1 = Map("a" -> 1, "b" -> 1, "c" -> 1)
m1: scala.collection.immutable.Map[java.lang.String,Int] = Map(a -> 1, b -> 1, c -> 1)
scala> val m2 = Map("a" -> 2, "c" -> 1)
m2: scala.collection.immutable.Map[java.lang.String,Int] = Map(a -> 2, c -> 1)
以 m1 和 m2 作为参数应用 add 会产生一个 List:
scala> add(m1,m2)
res3: Traversable[Any] = List((a,1), (b,1), (c,1), (a,2), (c,1))
...而想要的结果类似于直接使用 ++ 方法:
scala> m1 ++ m2
res0: scala.collection.immutable.Map[java.lang.String,Int] = Map(a -> 2, b -> 1, c -> 1)
使用定义为的集合 B 不会发生此问题:
class B[T] extends Iterable[T] with IterableLike[T, B[T]] { ... }
例如,队列以类似的方式实现。
队列示例:
scala> val q1 = Queue(9,2,5)
q1: scala.collection.immutable.Queue[Int] = Queue(9, 2, 5)
scala> val q2 = Queue(7,3,1)
q2: scala.collection.immutable.Queue[Int] = Queue(7, 3, 1)
在 q1 和 q2 上应用 add 可以得到想要的结果:
scala> add(q1,q2)
res4: Traversable[Any] = Queue(9, 2, 5, 7, 3, 1)
问题: 有没有一种方法可以实现add,使得对各种travesables(包括类似于Map实现的集合)的结果与直接使用++方法时的结果相同?我一直在尝试在 A 类的伴随对象中实现隐式 CanBuildFrom,但没有成功。在我看来,问题在于算法,而不是集合实现,因为它也不适用于 Map。