Scala 枚举和 readResolve

发布于 2024-08-03 06:46:36 字数 1895 浏览 3 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

三月梨花 2024-08-10 06:46:36

Scala 的 Enumeration 类的每个 ValuehashCode 都基于为它们创建的唯一数字 ID。它们不可序列化。您可以强制使用数值:

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

这应该会生成枚举的序列化版本,但请注意这些值与任何其他枚举之间可能会发生冲突。

但未经测试。

Scala bases the hashCode of each Value of its Enumeration class on the unique numeric ids created for them. They are not serializable. You may force the numeric value:

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文