我在代码中使用Kotlin“类型安全的构建器”模式:
insteadOf("search", "forest|ground") {
println("Do something.");
}
但是,我也使用Kryo序列化数据(保存游戏),而Kryo不喜欢匿名类型:
call: () -> Unit
因此,我不得不引入“ Do”接口,而不是上面的类型。但是现在我的代码看起来丑陋得多:
insteadOf("search", "forest|ground", object : World.InsteadOf.Do {
override fun invoke() {
println("Do something")
}
})
如何在Do接口中使用简单的{}-语法?
这里有一些澄清。
我有点困惑(不是新闻)。
实际的Kryo错误消息似乎与no-args构造函数有关,但是在此之后立即显示:“这是一个匿名类,默认情况下在Kryo中无法序列化。”
这是完整的错误消息:
Exception in thread "main" com.esotericsoftware.kryo.KryoException: Class cannot be created (missing no-arg constructor): fi.starstuff.rogue.World$insteadOf$1
This is an anonymous class, which is not serializable by default in Kryo. Possible solutions: 1. Remove uses of anonymous classes, including double brace initialization, from the containing class. This is the safest solution, as anonymous classes don't have predictable names for serialization.
2. Register a FieldSerializer for the containing class and call FieldSerializer#setIgnoreSyntheticFields(false) on it. This is not safe but may be sufficient temporarily. Use at your own risk.
Serialization trace:
call (com.mygame.World$InsteadOf)
insteadOfs (com.mygame.World)
at com.esotericsoftware.kryo.Kryo$DefaultInstantiatorStrategy.newInstantiatorOf(Kryo.java:1319)
at com.esotericsoftware.kryo.Kryo.newInstantiator(Kryo.java:1127)
at com.esotericsoftware.kryo.Kryo.newInstance(Kryo.java:1136)
这是代替类:
class InsteadOf {
var verbs: Array<String> = arrayOf()
var nouns: Array<String> = arrayOf()
var where: String = ""
var call: (() -> Unit)? = null
}
答案 0 :(得分:1)
您基本上可以在() -> Unit
中接受insteadOf
函数并将其包装到正文中的Do
实例中:
fun insteadOf(foo: String, bar: String, call: () -> Unit) {
val doInstance = World.InsteadOf.Do(call)
/* use doInstance */
}
用法将与第一个示例相同。
或者,为Do
接口提供一个工厂函数,该工厂函数接受() -> Unit
并返回一个Do
实例。
答案 1 :(得分:0)
尚不清楚您的代码有什么问题。 但是,如果您缺少无参数构造函数,则有两种方法:
no-arg
compiler plugin指定需要额外构造函数的类
org.jetbrains.kotlin:kotlin-noarg
许多与序列化相关的库迫使用户使用无参数构造函数。 在kryo github中有一个相关的issue。
如果您的问题与no-arg
不相关-您的问题将与this重复
答案 2 :(得分:0)
好吧,我最终只是转而使用核心Java序列化,问题就消失了。