Scala编译器无法推断Spark lambda函数内部的类型
假设我用Scala 2.12编写了这个Spark代码Scala编译器无法推断Spark lambda函数内部的类型,scala,apache-spark,lambda,apache-spark-dataset,Scala,Apache Spark,Lambda,Apache Spark Dataset,假设我用Scala 2.12编写了这个Spark代码 val dataset = spark.emptyDataset[String] dataset.foreachPartition( partition => partition.foreach { entry: String => println(entry) }) 当我运行代码时,编译器给出了这个错误 [info] Compiling 1 Scala source to <pa
val dataset = spark.emptyDataset[String]
dataset.foreachPartition( partition => partition.foreach {
entry: String => println(entry)
})
当我运行代码时,编译器给出了这个错误
[info] Compiling 1 Scala source to <path>/scala-2.12/classes ...
[error] Code.scala:11:52: value foreach is not a member of Object
[error] empty.foreachPartition( partition => partition.foreach{
[error] ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 1 s, completed Jul 11, 2020 1:43:41 AM
这是因为
foreachPartition
和javascala互操作的两个重载版本
如果代码仅在Scala中(这是最小的代码,与Spark无关)
然后将推断分区的类型
(如scala.collection.Iterator[String]
)
但在实际的Spark代码中,ForeachPartitionFunction是Java接口,其方法调用
接受Java.util.Iterator[String]
所以这两种选择
dataset.foreachPartition((
(partition: scala.collection.Iterator[String]) => ???
): Iterator[String] => Unit)
dataset.foreachPartition((
(partition: java.util.Iterator[String]) => ???
): ForeachPartitionFunction[String])
符合条件,并且编译器无法推断分区的类型
Scala中的推理是局部的,所以编译器可以看到partition=>partition.foreach…
(而且java.util.Iterator[String]
没有方法foreach
),现在再输入partition
就太迟了,就像@Dmytro所说的那样,scala编译器无法推断应该应用哪个重载函数。但是,通过使用此帮助器函数,您可以使用一个简单的解决方法:
def helper[I](f: I => Unit): I => Unit = f
现在,您需要做的就是:
dataset.foreachPartition( (partition:Iterator[String]) => partition.foreach {
helper[String](entry => println(entry))
})
这是一个由java过载引起的问题。你必须明确说明类型,没有解决办法,我怀疑Spark维护人员会做任何事情来改进Scala API,他们只关心Python和Java。@LuisMiguelMejíaSuárez,考虑到Scala被认为是Spark的一等公民,这很奇怪。许多年前确实如此。而且你不能责怪他们,简单的营销是Scala用户所占的比例是少数。
def helper[I](f: I => Unit): I => Unit = f
dataset.foreachPartition( (partition:Iterator[String]) => partition.foreach {
helper[String](entry => println(entry))
})