Kotlin类型安全的构建器

时间:2018-09-11 11:04:22

标签: kotlin

我在代码中使用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
    }

3 个答案:

答案 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)

尚不清楚您的代码有什么问题。 但是,如果您缺少无参数构造函数,则有两种方法:

  1. 显然将其添加
  2. 使用no-arg compiler plugin指定需要额外构造函数的类 org.jetbrains.kotlin:kotlin-noarg

许多与序列化相关的库迫使用户使用无参数构造函数。 在kryo github中有一个相关的issue

如果您的问题与no-arg不相关-您的问题将与this重复

答案 2 :(得分:0)

好吧,我最终只是转而使用核心Java序列化,问题就消失了。