Scala 枚举和 readResolve
Scala 的 Enumeration
类和 Enumeration.Val
readResolve
方法似乎没有按其应有的方式工作(可能与 Scala trac 中的此条目)。这是 *Steve Bendiola 提供的程序来说明问题:
@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
}
}
}
这个程序的输出当然不应该 看起来像:
有债务
未知: scala.Enumeration$Val 类的未来
未知:EQUITY of:class scala.Enumeration$Val
它似乎与声明枚举值的顺序有关。对它们重新排序,似乎第一个值总是被合理地解析
Scala's Enumeration
class and the Enumeration.Val
readResolve
method do not appear to work as they should do (possibly related to this entry in Scala trac). Here is a program provided by *Steve Bendiola" to illustrate the problem:
@serializable
object InvestmentType extends Enumeration {
val Debt = Value("DEBT")
val Future = Value("FUTURE")
val Equity = Value("EQUITY")
}
Now a Main
class which can be run either with an arument W
where it will write out the enumeration values to a file, or R
where it will read them back in again:
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
}
}
}
Both these methods require this foreach
method:
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
}
}
}
The output of this program should certainly not look like:
got DEBT
unknown: FUTURE of: class scala.Enumeration$Val
unknown: EQUITY of: class scala.Enumeration$Val
It appears to be related to which order the enumeration values are declared. Reordering them, it appears that the first value is always sensibly resolved
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Scala 的
Enumeration
类的每个Value
的hashCode
都基于为它们创建的唯一数字 ID。它们不可序列化。您可以强制使用数值:这应该会生成枚举的序列化版本,但请注意这些值与任何其他枚举之间可能会发生冲突。
但未经测试。
Scala bases the
hashCode
of eachValue
of itsEnumeration
class on the unique numeric ids created for them. They are not serializable. You may force the numeric value:This ought to produce a serializale version of the enumeration, but mind that you could have a collision between these values and any other enumeration.
Untested, though.