1

私はscalaプログラミング言語にまったく慣れていないため、現在次のことを行う必要があります。次のような signleton オブジェクトがあります。

object MyObject extends Serializable {
    val map: HashMap[String, Int] = null
    val x: int = -1;
    val foo: String = ""
}

このオブジェクトの各フィールドを個別にシリアル化する必要がないようにしたいので、オブジェクト全体をファイルに書き込み、次にプログラムを実行するときにファイルを読み取り、そこからシングルトン オブジェクトを初期化することを検討していました。これを行う方法はありますか?

基本的に私が欲しいのは、シリアル化ファイルが存在しない場合、それらの変数は新しい構造に初期化され、存在する場合はフィールドがファイル上のものから初期化されることです。しかし、すべてのフィールドを手動でシリアライズ/デシリアライズする必要は避けたい...

アップデート:

ここに示されているように、カスタム デシリアライザーを使用する必要がありました: https://issues.scala-lang.org/browse/SI-2403、HashMap 内で値として使用するカスタム クラスに問題があったためです。

更新 2:

シリアル化に使用するコードは次のとおりです。

val store = new ObjectOutputStream(new FileOutputStream(new File("foo"))) 
store.writeObject(MyData) 
store.close

逆シリアル化するコード (別のファイル内):

@transient private lazy val loadedData: MyTrait = {
    if(new File("foo").exists()) {
        val in = new ObjectInputStream(new FileInputStream("foo")) {
            override def resolveClass(desc: java.io.ObjectStreamClass): Class[_] = {
                try { Class.forName(desc.getName, false, getClass.getClassLoader) }
                catch { case ex: ClassNotFoundException => super.resolveClass(desc) }
            }
        }
        val obj = in.readObject().asInstanceOf[MyTrait] 
        in.close
        obj
    }
    else null
}

ありがとう、

4

1 に答える 1

1

不変フィールドのみでオブジェクトをシリアル化する必要はありません (コンパイラーがそれを行うため...)。オブジェクトがデフォルト値を提供すると仮定します。これを行う方法は次のとおりです。

すべての必須フィールドを含むトレイトを作成することから始めます。

trait MyTrait {
  def map: HashMap[String, Int]
  def x: Int
  def foo: String
}

次に、デフォルトでオブジェクトを作成します。

object MyDefaults extends MyTrait {
  val map = Map()
  val x = -1
  val foo = 
}

最後に、データが存在する場合、データを非シリアル化する実装を記述します。

object MyData extends MyTrait {

  private lazy val loadedData: Option[MyTrait] = {
     if( /* filename exists */ ) Some( /*unserialize filename as MyTrait*/)
    else None
  }
  lazy val map = loadedData.getOrElse( MyDefault ).map
  lazy val x = loadedData.getOrElse( MyDefault ).x
  lazy val foo = loadedData.getOrElse( MyDefault ).foo

}
于 2012-12-05T10:11:17.693 に答える