2009-09-03 82 views
3

斯卡拉的Enumeration類和Enumeration.ValreadResolve方法似乎不工作,因爲他們應該這樣做(可能與this entry in Scala trac)。下面是*史蒂夫Bendiola」提供的程序來說明這個問題:斯卡拉枚舉和readResolve

@serializable 
object InvestmentType extends Enumeration { 
    val Debt = Value("DEBT") 
    val Future = Value("FUTURE") 
    val Equity = Value("EQUITY") 
} 

現在Main類可以用arument W它會寫出來的枚舉值到一個文件中運行要麼,或R哪裏它會再次讀回:

object Main { 
    def main(args: Array[String]) = { 
    args(0) match { 
     case "R" => { 
     val ois = new ObjectInputStream(new FileInputStream("enum.ser")) 
     var obj: Object = null 

     foreach(ois) { obj => 
       obj match { 
       case InvestmentType.Debt => println("got " + obj) 
       case InvestmentType.Equity => println("got " + obj) 
       case InvestmentType.Future => println("got " + obj) 
       case _ => println("unknown: " + obj + " of: " + obj.getClass) 
       } 
     } 
     } 

     case "W" => { 
     val oos = new ObjectOutputStream(new FileOutputStream("enum.ser")) 
     InvestmentType.foreach {i => oos.writeObject(i)} 
     oos.flush 
     oos.close 
     } 
    } 
    } 

這兩種方法都需要這種foreach方法:

def foreach(os: ObjectInputStream)(f: Object => Unit) { 
    try { 
     val obj = os.readObject 
     if (obj != null) { 
     f(obj) 
     foreach(os)(f) 
     } 
    } catch { 
     case e: EOFException => //IGNORE 
    } 
    } 
} 

這個程序的輸出應該肯定樣子:

got DEBT
unknown: FUTURE of: class scala.Enumeration$Val
unknown: EQUITY of: class scala.Enumeration$Val

這似乎是到次序值聲明的枚舉有關。重新排列它們,看來第一個值總是理智的方法消除

回答

1

斯卡拉立足其Enumeration類的每個ValuehashCode上爲他們創造獨特的數字ID。它們不是可序列化的。你可能會迫使數值:

object InvestmentType extends Enumeration { 
    val Debt = Value(1, "DEBT") 
    val Equity = Value(2, "EQUITY") 
    val Future = Value(3, "FUTURE") 
} 

這應該產生枚舉的serializale版本,但記住,你可以有這些價值和其他任何枚舉之間的衝突。

雖然未經測試。

+0

丹尼爾 - 正如我在Scala用戶的郵件列表中所提到的,該問題與'hashCode'無關。我只是在單個JVM中使用Enumeration值的'identityHashCode'來顯示'Enumeration.Val'類的'readResolve'方法工作不正常 – 2009-09-03 15:23:38

+0

這個問題對於你來說太簡單了。 :-) 是的,我看見它了。 – 2009-09-04 11:27:47