Scala @瞬时延迟val字段序列化
我在Scala上有个问题。我用Scala @瞬时延迟val字段序列化,scala,lazy-evaluation,transient,Scala,Lazy Evaluation,Transient,我在Scala上有个问题。我用@transient lazy val字段序列化类的实例。然后我对它进行反序列化,字段被赋值为null。我希望在反序列化之后进行延迟计算。我该怎么办 下面是一个示例代码 object Test { def main(args: Array[String]){ //---------------- // ClassA - with @transient //---------------- val objA1 = ClassA
@transient lazy val
字段序列化类的实例。然后我对它进行反序列化,字段被赋值为null
。我希望在反序列化之后进行延迟计算。我该怎么办
下面是一个示例代码
object Test {
def main(args: Array[String]){
//----------------
// ClassA - with @transient
//----------------
val objA1 = ClassA("world");
println(objA1);
// This works as expected as follows:
// "Good morning."
// "Hello, world"
saveObject("testA.dat", objA1);
val objA2 = loadObject("testA.dat").asInstanceOf[ClassA];
println(objA2);
// I expect this will work as follows:
// "Good morning."
// "Hello, world"
// but actually it works as follows:
// "null"
//----------------
// ClassB - without @transient
// this works as expected
//----------------
val objB1 = ClassB("world");
println(objB1);
// This works as expected as follows:
// "Good morning."
// "Hello, world"
saveObject("testB.dat", objB1);
val objB2 = loadObject("testB.dat").asInstanceOf[ClassB];
println(objB2);
// This works as expected as follows:
// "Hello, world"
}
case class ClassA(name: String){
@transient private lazy val msg = {
println("Good morning.");
"Hello, " + name;
}
override def toString = msg;
}
case class ClassB(name: String){
private lazy val msg = {
println("Good morning.");
"Hello, " + name;
}
override def toString = msg;
}
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
def saveObject(fname: String, obj: AnyRef){
val fop = new FileOutputStream(fname);
val oop = new ObjectOutputStream(fop);
try {
oop.writeObject(obj);
} finally {
oop.close();
}
}
def loadObject(fname: String): AnyRef = {
val fip = new FileInputStream(fname);
val oip = new ObjectInputStream(fip);
try {
oip.readObject();
} finally {
oip.close();
}
}
}
Scala的Trac上有几张票:
我建议您使用2.9的主干版本进行测试,因为它可能已经修复。非常感谢。我将尝试2.9。这只是一个在Scala 2.10.4中运行良好的更新。但是,我注意到,如果初始值设定项依赖于by-name参数,它仍然会被破坏。例如,将ClassA.name设为
=>String
,它将不起作用。(您还需要将其设置为扩展Serializable的非case类,并将name设置为val。)