gpt4 book ai didi

apache-spark - 避免在类中使用嵌套方法出现 "Task not serialisable"

转载 作者:行者123 更新时间:2023-12-03 07:04:50 25 4
gpt4 key购买 nike

我理解访问超出闭包范围的字段或方法时出现的常见“任务不可序列化”问题。

为了解决这个问题,我通常定义这些字段/方法的本地副本,这样就不需要序列化整个类:

class MyClass(val myField: Any) { 
def run() = {
val f = sc.textFile("hdfs://xxx.xxx.xxx.xxx/file.csv")

val myField = this.myField
println(f.map( _ + myField ).count)
}
}

现在,如果我在 run 方法中定义嵌套函数,它就无法序列化:

class MyClass() { 
def run() = {
val f = sc.textFile("hdfs://xxx.xxx.xxx.xxx/file.csv")

def mapFn(line: String) = line.split(";")

val myField = this.myField
println(f.map( mapFn( _ ) ).count)

}
}

我不明白,因为我认为“mapFn”将在范围内......更奇怪的是,如果我将 mapFn 定义为 val 而不是 def,那么它就可以工作:

class MyClass() { 
def run() = {
val f = sc.textFile("hdfs://xxx.xxx.xxx.xxx/file.csv")

val mapFn = (line: String) => line.split(";")

println(f.map( mapFn( _ ) ).count)
}
}

这与 Scala 表示嵌套函数的方式有关吗?

处理此问题的建议方法是什么?避免嵌套函数?

最佳答案

它不是以这种方式工作吗,因此在第一种情况下 f.map(mapFN(_)) 相当于 f.map(new Function() { override def apply(...) = mapFN(...) }) 而在第二个中它只是 f.map(mapFN)?当您使用 def 声明一个方法时,它可能只是某个匿名类中的一个方法,并且隐式地引用了封闭类的 $outer 引用。但是 map 需要一个 Function,因此编译器需要包装它。在包装器中,您只需引用该匿名类的某些方法,而不是实例本身。如果您使用 val,则可以直接引用传递给 map 的函数。我对此不太确定,只是大声思考......

关于apache-spark - 避免在类中使用嵌套方法出现 "Task not serialisable",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23732999/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com