2009-09-03 81 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