7

我有这个函数将 a转换Array为 a ParArray,将线程数作为参数:

def parN[T](collection: Array[T], n: Int) = {
    val parCollection = collection.par
    parCollection.tasksupport = new ForkJoinTaskSupport(
      new concurrent.forkjoin.ForkJoinPool(n))
    parCollection
}

现在我想让这个通用,这样它就可以与以下集合一起使用Array

def parN[S, T[S] <: Parallelizable[S, ParIterable[S]]](collection: T[S], n: Int) = {
    val parCollection = collection.par
    parCollection.tasksupport = new ForkJoinTaskSupport(
      new concurrent.forkjoin.ForkJoinPool(n))
    parCollection
}

但是当我用 调用它parN(Array(1, 2, 3), 2),我得到了这个错误:

inferred type arguments [Int,Array] do not
conform to method parN's type parameter bounds
[S,T[S] <: scala.collection.Parallelizable[S,scala.collection.parallel.ParIterable[S]]]

另一方面,这是有效的:

val x: Parallelizable[Int, ParIterable[Int]] = Array(1, 2, 3)

任何想法我的类型参数可能有什么问题?

4

1 回答 1

5

首先,请注意这是一个特定于 的问题Array:您的方法适用于List或任何其他普通集合(具有多个类型参数或没有的那些除外)。例子:

scala> parN(List(1,2,3), 2)
res17: scala.collection.parallel.ParIterable[Int] = ParVector(1, 2, 3)

scala> parN(Set(1,2,3), 2)
res18: scala.collection.parallel.ParIterable[Int] = ParSet(1, 2, 3)

Array当涉及到集合时,它总是一个特例,因为......它不是一个集合。因为Java,它的定义是final class Array[T] extends Serializable with Cloneable. 但是,存在两个可以转换Array为集合类型(ArrayOpsWrappedArray)的隐式,随处可用。而且这些类型确实实现Parallelizable了,所以一切都应该没问题......除了类型推断会妨碍:

您的类型参数仅定义为T[S],因此当接收到 时Array[Int],它会很乐意推断Array[Int],然后检查边界:失败,Array不扩展Parallelizable。游戏结束。

我看到两个选项:

  • 你可以明确地说你想要一个Parallelizable

    def parN[S](collection: Parallelizable[S, ParIterable[S]], n: Int)
    

    或者,如果您需要访问实际类型T(在您的情况下没有,但谁知道):

    def parN[S, T[S] <: Parallelizable[S, ParIterable[S]]](collection: T[S] with
       Parallelizable[S, ParIterable[S]], n: Int)
    
  • 或者您可以使用隐式参数接受任何可以隐式转换为 a的内容Parallelizable

    def parN[S, T <% Parallelizable[S, ParIterable[S]]](collection: T, n: Int)
    

    这是以下的简短版本:

    def parN[S, T](collection: T, n: Int)(implicit ev: T => 
      Parallelizable[S, ParIterable[S]])
    

所有这些都应该工作。在您的情况下,我会推荐第一个:它是完成这项工作的最易读的。

于 2013-05-24T13:07:22.727 回答