【问题标题】:Kotlin type-safe buildersKotlin 类型安全构建器
【发布时间】:2018-09-18 15:47:54
【问题描述】:

我在我的代码中使用 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-interface 中使用简单的 { } - 语法?

编辑:

这里有一些说明。

我有点困惑(不是新闻)。

实际的 Kryo 错误消息似乎与无参数构造函数有关,但紧接着它说:“这是一个匿名类,默认情况下在 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
    }

【问题讨论】:

  • “不喜欢匿名类型”是什么意思?

标签: kotlin


【解决方案1】:

您基本上可以在insteadOf 中接受() -&gt; Unit 函数并将其包装到主体中的Do 实例中:

fun insteadOf(foo: String, bar: String, call: () -> Unit) { 
    val doInstance = World.InsteadOf.Do(call)
    /* use doInstance */
}

用法与您的第一个示例相同。

或者,为Do 接口提供一个接受() -&gt; Unit 并返回Do 实例的工厂函数。

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

      好吧,我只是最终切换到核心 Java 序列化,问题就消失了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-06
        • 1970-01-01
        • 2015-06-13
        • 2023-03-04
        相关资源
        最近更新 更多