问题描述
我知道有 Jerkson 和 scalaxb 甚至 Java 的 XStream 能够成功地序列化 scala 的数据.我知道他们可以很好地处理字符串、整数甚至案例类.但是,如果我将功能作为字段之一?
I know that there is Jerkson and scalaxb and even Java's XStream that successfully able to serialize scala's data. I know that they handle well Strings, Integers and even case classes pretty well. But if I have function as one of the fields?
例如如果我有类似的东西:
e.g. if I have something like:
case class Foo(bar: (Int) => Boolean, baz: Int)
这些字段能否以某种方式序列化为 JSON 或 XML(实际上,我不在乎是哪一个,它们应该是人类可读的,这就是为什么我不想使用 SBinary)?
Can these fields been somehow serialized to JSON or XML (actually, I don't care to which one, they should be human-readable, thats why I don't want to use SBinary)?
我为什么要这样做?现在我正在编写决策树的实现.我不想每次都从训练数据中重建那些树,因此我需要序列化它们,这部分可以用 SBinary 完成.但另外,如果作为人类我们可以查看序列化树并对其进行分析,那就太好了.
Why would I want to do that?Right now I'm writing implementation of decision tree. I don't want to reconstruct that trees every time from training data hence I need to serialize them and that part could be done with SBinary. But additionally, it would be nice if as a humans we could look at serialized tree and analyze it.
这不是我在标题中写的那么广泛的任务,是的.我现在想的是用我自己的格式编写自定义序列化程序(例如用于 Jerkson),或者写入字符串字段然后解析它.
It is not so wide task as I wrote in title, yes.What I thinking now, is to write a custom serializer (e.g. for Jerkson) with my own format, or write to string field and then parse this back.
但我认为可能有一些更好的方法来执行此操作.
But I though that there could be some insanely better way to perform that.
推荐答案
不,函数不是必须可序列化的...而且可序列化的函数不太可能提供人类可读的序列化.
No, a function is not necessary serializable... and serializable functions are unlikely to provide a human readable serialization.
如果你想能够提供任何一种功能,恐怕没有任何解决方案.如果可以在您的场景中使用,一个可能的解决方法是构建一个实现 Function[Int, Boolean]
的案例类,从而返回到案例类场景.
If you want to be able to provide any kind of function, Im' afraid there won't be any solution. A possible workaround, if it can be used in your scenario, is to build a case class that implements Function[Int, Boolean]
and thus to go back to a case class scenario.
例如,假设您已隔离所有函数检查整数是否可以被给定整数整除:
For example, suppose that you have isolated that all your functions check whether a integer is exactly divisible by a given integer:
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)
这显然是非常严格的.但恐怕这是你能做到的最好的.
It's clearly ultra-restrictive. But I'm afraid it's the best you can achieve.
根据您的编辑.一种解决方案可能是拥有一种工厂类:
According to your edit. A solution might be to have a kind of factory class:
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)
但是在这里,您将失去类型安全性.
But here, you will lose type safety.
这篇关于scala 函数的序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!