0

我想定义一个通用集合的转换。

def transform[S<:GenIterable[T],T](s:S):S = s.zipWithIndex

这抛出:

type mismatch; found : scala.collection.GenIterable[(T, Int)] required: S

我必须在函数定义中声明S为参数化。GenIterable我想指定一个输出类型“无论创建的集合类型是什么S,用参数化的除外[(T,Int)]”,这样我就可以保证得到相同的集合类型,而不仅仅是GenIterable.

我怎样才能做到这一点?

4

1 回答 1

3

这是我的存根:

def transform[S[T]<: GenIterableLike[T,S[T]],T](s:S[T])
  (implicit bf:CanBuildFrom[S[T],(T,Int),S[(T,Int)]]):S[(T,Int)] = {

  s.zipWithIndex
}

T签名很糟糕,通过替换它可能会稍微简化(或模糊)_

试一试:

scala> val m = Map("x"->"1","y"->"2")
m: scala.collection.Map[String,String] = Map(x -> 1, y -> 2)

scala> transform(m)
res3: Iterable[((String, String), Int)] = List(((x,1),0), ((y,2),1))

scala> val s = Set("x", "y")
s: scala.collection.Set[String] = Set(x, y)

scala> transform(s)
res4: scala.collection.Set[(String, Int)] = Set((x,0), (y,1))

scala> val seq = List("x", "y")
seq: List[String] = List(x, y)

scala> transform(seq)
res5: List[(String, Int)] = List((x,0), (y,1))

关键是使用Liketrait,因为它带有正在使用的集合的类型。然后,隐式转换负责其余的工作。注意,如何Map处理。似乎隐式转换默认为转换IterableList,这是有道理的。

于 2015-09-10T00:39:36.637 回答