scala parallel set递归值需要类型

时间:2014-11-02 15:04:48

标签: scala parallel-processing par

我有一个来自'Scala in depth'的代码,可以在交互式编辑器中使用:

(1 to 1000).par map { _ => Thread.currentThread.toString } toSet

这将打印一个包含用于此并行操作的线程的集合。一切都很好,结果类型是ParSet [String]

但是我尝试在代码中使用它,我有这个:

val pthr = (1 to 1000).par map { _ => Thread.currentThread.toString } toSet
//val x = pthr.toSet
println("thread = " + pthr)

抛出:println行中的“错误:递归值pthr需要类型”。另一个观察是当我取消注释第二行时,一切正常,结果是ParSet()。

这里发生了什么?什么是变量“pthr”?

2 个答案:

答案 0 :(得分:0)

println方法需要一个字符串,并且您已经为pthr提供了一个带有+运算符的字符串。为了将pthr转换为字符串,编译器需要知道它是哪种类型。您没有在pthr声明中提供类型,而是推断它。无论出于何种原因,推理都不起作用,因此编译器正在请求显式类型声明。你可以这样做:

val pthr : Set[String] = (1 to 1000).par map { _ => Thread.currentThread.toString } toSet

这应该照顾它。

但是,我无法使用Scala 2.11.2重现您的结果。我明白了:

scala> val pthr = (1 to 1000).par map { _ => Thread.currentThread.toString } toSet
<console>:7: warning: postfix operator toSet should be enabled
by making the implicit value scala.language.postfixOps visible.
This can be achieved by adding the import clause 'import scala.language.postfixOps'
or by setting the compiler option -language:postfixOps.
See the Scala docs for value scala.language.postfixOps for a discussion
why the feature should be explicitly enabled.
       val pthr = (1 to 1000).par map { _ => Thread.currentThread.toString } toSet
                                                                             ^
pthr: scala.collection.parallel.immutable.ParSet[String] = ParSet(Thread[ForkJoinPool-1-worker-29,5,main], Thread[ForkJoinPool-1-worker-19,5,main], Thread[ForkJoinPool-1-worker-13,5,main], Thread[ForkJoinPool-1-worker-3,5,main], Thread[ForkJoinPool-1-worker-27,5,main], Thread[ForkJoinPool-1-worker-5,5,main], Thread[ForkJoinPool-1-worker-1,5,main], Thread[ForkJoinPool-1-worker-23,5,main], Thread[ForkJoinPool-1-worker-15,5,main], Thread[ForkJoinPool-1-worker-11,5,main], Thread[ForkJoinPool-1-worker-21,5,main], Thread[ForkJoinPool-1-worker-9,5,main], Thread[ForkJoinPool-1-worker-7,5,main], Thread[ForkJoinPool-1-worker-17,5,main], Thread[ForkJoinPool-1-worker-31,5,main], Thread[ForkJoinPool-1-worker-25,5,main])

scala> println("thread = " + pthr)
thread = ParSet(Thread[ForkJoinPool-1-worker-29,5,main], Thread[ForkJoinPool-1-worker-19,5,main], Thread[ForkJoinPool-1-worker-13,5,main], Thread[ForkJoinPool-1-worker-3,5,main], Thread[ForkJoinPool-1-worker-27,5,main], Thread[ForkJoinPool-1-worker-5,5,main], Thread[ForkJoinPool-1-worker-1,5,main], Thread[ForkJoinPool-1-worker-23,5,main], Thread[ForkJoinPool-1-worker-15,5,main], Thread[ForkJoinPool-1-worker-11,5,main], Thread[ForkJoinPool-1-worker-21,5,main], Thread[ForkJoinPool-1-worker-9,5,main], Thread[ForkJoinPool-1-worker-7,5,main], Thread[ForkJoinPool-1-worker-17,5,main], Thread[ForkJoinPool-1-worker-31,5,main], Thread[ForkJoinPool-1-worker-25,5,main])

除了使用toSet方法作为postFix运算符之外,代码没有任何问题,它可以正确编译和执行。也许你应该检查你的编译器版本?

答案 1 :(得分:0)

是的我知道这可以在交互式scala中使用,但在scalac编译时不会。

好的,这是简约的例子让我们称这个文件为“ test.scala ”:

//test.scala
object test {
  def main(args: Array[String]) = {
    val pthr = (1 to 1000).par map { _ => Thread.currentThread.toString } toSet
    println("thread = " + pthr)
  }
}

现在让我们在终端执行:

-> scalac test.scala                                              
test.scala:5: error: recursive value pthr needs type
println("thread = " + pthr)
                      ^
one error found

-> scalac -version                             
Scala compiler version 2.11.2 -- Copyright 2002-2013, LAMP/EPFL

所以我只在使用scalac进行编译时再次遇到此问题。

当我向pthr(val pthr: Set[String] = ...)添加一个类型时,错误是:

test.scala:4: error: type mismatch;
 found   : Boolean
 required: Set[String]
    val pthr:Set[String] = (1 to 1000).par map { _ => Thread.currentThread.toString } toSet
                                                                                  ^
one error found

不知道发生了什么:/

顺便说一句。这是从第205页的“Scala中的深度”复制的确切代码。