为什么 Scala 方法可以序列化而函数不能序列化?

zin*_*ing 5 scala apache-spark

我有一个像这样定义的 spark RDD:

val dataset = CreateRDD(data.filter(someFilter))
Run Code Online (Sandbox Code Playgroud)

我观察到以下情况:

//if filter is defined as function, such as following, 
//then spark will throw spark `task not serialisable exception`
val someFilter = (some) => true
//if filter is defined as method, such as following then everything will be fine
def someFilter(some) => true
Run Code Online (Sandbox Code Playgroud)

为什么 ?

是的,函数/方法都被定义为测试规范中的成员

kap*_*nga 3

问题是这样的:

val isNegative = (num: Int) => num < 0
Run Code Online (Sandbox Code Playgroud)

只是语法糖:

val isNegative = new Function1[Int, Boolean] {
  def apply(num: Int): Boolean = num < 0
}
Run Code Online (Sandbox Code Playgroud)

Function1是一个 Trait 并且创建的匿名函数不可序列化。当你有这样的事情时:

object Tests {
  def isNegative(num: Int): Boolean = num < 0
}
Run Code Online (Sandbox Code Playgroud)

现在isNegative是一个Tests可序列化的成员。当你这样调用时:

val dataset = CreateRDD(data.filter(isNegative))
Run Code Online (Sandbox Code Playgroud)

isNegativeSpark在将其发送到每个节点之前需要进行序列化。由于对象是可序列化的,如果它的所有成员都是可序列化的,那么当您使用def它时它工作正常,但是当您使用valSpark 时,它将尝试序列化 的值isNegative,这是一个不可序列化的匿名函数并失败。