我有一个来自'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”?
答案 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中的深度”复制的确切代码。