클로저 범위를 벗어난 필드 또는 메서드에 액세스 할 때 발생하는 일반적인 "작업 직렬화 불가능"문제를 이해합니다.
이를 수정하기 위해 일반적으로 이러한 필드 / 메서드의 로컬 복사본을 정의하여 전체 클래스를 직렬화 할 필요가 없습니다.
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을 def 대신 val로 정의하면 작동합니다.
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
.NET에 전달하는 함수에 대한 직접 참조가 있습니다 map
. 나는 이것에 대해 잘 모르겠다, 단지 큰 소리로 생각한다 ...
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다