1

我有一个来自“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”的类型?

4

2 回答 2

0

该方法需要一个字符串,并且您已经为 pthrprintln提供了一个带有运算符的字符串。+为了将 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 运算符之外,代码没有任何问题,并且可以正确编译和执行。也许您应该检查您的编译器版本?

于 2014-11-02T15:24:50.347 回答
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

不知道发生了什么:/

顺便提一句。这是从“Depth in scala”第 205 页复制的确切代码。

于 2014-11-02T16:08:29.063 回答