2016-06-14 79 views
2

我有一個對象下類似地定義2個函數(其中1是局部的):爲什麼Scala可以序列化Function而不是PartialFunction?

val partialFn: scala.PartialFunction[String, Int] = 
    new AbstractPartialFunction[String, Int] { 

     override def isDefinedAt(v: String): Boolean = { 
     counter += 1 
     if (v == "abc") true 
     else false 
     } 

     override def applyOrElse[A1 <: String, B1 >: Int](v: A1, default: A1 => B1): B1 = { 
     counter += 1 
     if (v == "abc") { 
      v.length 
     } 
     else { 
      default(v) 
     } 
     } 
    } 

    val optionFn: (String) => Option[Int] = { 
    (v: String) => { 
     counter += 1 
     if (v == "abc") { 
     Some(v.length) 
     } 
     else { 
     None 
     } 
    } 
    } 

當它們都包裹在一個選項(絕對序列化的)和被序列化/反序列化,它們中的一個失敗:

java.io.NotSerializableException: ***.extractors.ExtractorSuite$$anon$1 
Serialization stack: 
    - object not serializable (class: ***.extractors.ExtractorSuite$$anon$1, value: <function1>) 
    - field (class: scala.Some, name: x, type: class java.lang.Object) 
    - object (class scala.Some, Some(<function1>)) 
    at org.apache.spark.serializer.SerializationDebugger$.improveException(SerializationDebugger.scala:40) 
    at org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:47) 
    at org.apache.spark.serializer.JavaSerializerInstance.serialize(JavaSerializer.scala:101) 
    at ***.tests.TestMixin$$anonfun$assertSerializable$1.apply(TestMixin.scala:61) 

... 

任何想法爲什麼PartialFunction &常用函數有這麼大的區別?

回答

2

因爲您明確創建AbstractPartialFunction而不會延伸Serializable。如果你對new AbstractFunction1[String, Int] { ... }也這樣做,它也不會被序列化。另一方面,當您使用匿名函數語法時,編譯器會生成一個擴展爲Serializable的類。這包括匿名部分函數語法:

scala> val x: PartialFunction[Int, Boolean] = { case 0 => true } 
x: PartialFunction[Int,Boolean] = <function1> 

scala> x.isInstanceOf[Serializable] 
res0: Boolean = true 
scala> val x: PartialFunction[Int, Boolean] = { case 0 => true } 
x: PartialFunction[Int,Boolean] = <function1> 

scala> x.isInstanceOf[Serializable] 
res0: Boolean = true 
+0

我明白了,所以=>語法糖會自動生成一個Serializable,但是case:=> sugar不會?請讓我確認你在REPL上的觀察 – tribbloid

+0

不,他們都這麼做。我編輯了答案,使其更清晰。 –

相關問題