om-*_*nom 10 serialization scala
我知道Jerkson和scalaxb甚至Java的XStream都能成功地序列化scala的数据.我知道他们很好地处理了Strings,Integers甚至是case类.但是,如果我有一个领域的功能?
例如,如果我有类似的东西:
case class Foo(bar: (Int) => Boolean, baz: Int)
Run Code Online (Sandbox Code Playgroud)
这些字段可以以某种方式序列化为JSON或XML(实际上,我不关心哪一个,它们应该是人类可读的,这就是为什么我不想使用SBinary)?
我为什么要那样做?现在我正在编写决策树的实现.我不想每次从训练数据重建那些树,因此我需要序列化它们,那部分可以用SBinary完成.但另外,如果作为人类我们可以查看序列化树并进行分析,那将是很好的.
这不是我在标题中写的那么广泛的任务,是的.我现在想的是用自己的格式编写一个自定义序列化程序(例如Jerkson),或写入字符串字段然后解析它.
但我认为可能有一些疯狂的更好的方式来执行.
use*_*956 12
是.这是可能的,只是让我大吃一惊:
import java.io._
def write[A](obj: A): Array[Byte] = {
val bo = new ByteArrayOutputStream()
new ObjectOutputStream(bo).writeObject(obj)
bo.toByteArray
}
def read(bytes:Array[Byte]): Any = {
new ObjectInputStream(new ByteArrayInputStream(bytes)).readObject()
}
read(write( {a:Int => a+1} )).asInstanceOf[ Function[Int,Int] ](5) // == 6
// And case class serialization
case class XF(f:(Int => Int)) extends Serializable
read(write(XF( {a:Int => a+1} ))).asInstanceOf[XF].f(5) // == 6
Run Code Online (Sandbox Code Playgroud)
NB.不适用于在外部类或函数范围内定义的类.(这很有意义,因为你可能并不意味着序列化对外部类的引用).
非常酷,但请注意,当加载对象时,JVM要求加载的类引用在类路径中可用.(这不是一个通用的序列化路径,因为读者还需要访问被反序列化的编译类文件)
不,函数不是必需的可序列化的......并且可序列化的函数不太可能提供人类可读的序列化.
如果您希望能够提供任何功能,我担心不会有任何解决方案.如果可以在您的场景中使用,可能的解决方法是构建一个实现的案例类,Function[Int, Boolean]从而返回到案例类场景.
例如,假设您已经隔离了所有函数检查整数是否可以被给定的整数整除:
case class Mod(mod: Int) extends Function[Int, Boolean] { //the extends part is not even require
def apply(x: Int) = x % mod == 0
}
case class Foo(bar: Mod, baz: Int)
Run Code Online (Sandbox Code Playgroud)
这显然是超限制性的.但我担心这是你能做到的最好的.
根据你的编辑.解决方案可能是拥有一种工厂类:
case class IntTest(humanReadableDescription: String) {
def apply(x: Int) = IntTest.fromString(humanReadableDescription)(x)
}
object IntTest {
private val fromString = Map[String, Function[Int, Boolean]] (
"mod2" -> {x:Int => x % 2 == 0},
"is42" -> {x:Int => x == 42}
)
}
case class Foo(bar: IntTest, baz: Int)
Run Code Online (Sandbox Code Playgroud)
但在这里,你将失去类型安全.
| 归档时间: |
|
| 查看次数: |
8045 次 |
| 最近记录: |