【问题标题】:Why is the Scala compiler giving me an error when passing a Kotlin sealed class into a constructor?为什么在将 Kotlin 密封类传递给构造函数时 Scala 编译器会给我一个错误?
【发布时间】:2016-09-27 00:17:48
【问题描述】:

我有一个用 Kotlin 编写的密封类:

sealed class Schema {
    class RecordSchema(val fields: List<Field>): Schema()
    class ArraySchema(val elementSchema: Schema): Schema()
    ...
}

还有一个以RecordSchema为参数的类:

class Enrichment(config: Config, val schema: RecordSchema) { ... }

在 Scala 中,我有一个类,除其他外,它获取 RecordSchema 的实例,然后创建 Enrichment 的实例。

object Job {
    def main(args: Array[String]): Unit = {
        /// some initializing of resources... and then...
        val recordSchema = schemas.getSchema(id) // type is Schema.RecordSchema
        val enrichment = Enrichment(config, recordSchema) // this is where scalac errors out
    }
}

scala 编译器最终打印此错误消息:

Error:(52, 62) type mismatch;
 found   : com.companyname.enricher.schemas.com.companyname.enricher.schemas.com.companyname.enricher.schemas.
 required: com.companyname.enricher.schemas.(some other)com.companyname.enricher.schemas.com.companyname.enricher.schemas.
    val enrichment = new Enrichment(config, recordSchema)

如果我使用asInstanceOf 投射recordSchema,我会得到另一个不太有用的错误:

Error:(52, 62) type mismatch;
 found   : com.companyname.enricher.schemas.Schema.RecordSchema
 required: com.companyname.enricher.schemas.com.companyname.enricher.schemas.
    val enrichment = new Enrichment(config, recordSchema.asInstanceOf[RecordSchema])

总的来说,我不知道为什么会这样。如果我让构造函数将父类作为参数而不是嵌套类,它编译得很好(这是我现在的解决方法)。如果我做同样类型的事情,除了用 Java 而不是 Kotlin 编写源代码,这个错误就不会发生。我正在使用 Java 1.8、Kotlin 1.0.4、Scala 2.11.8。

更新:

这里显示的错误: https://github.com/mjburghoffer/scala-kotlin-innerclass-bug/tree/master

【问题讨论】:

  • 我猜你需要val recordSchema:Schema = schemas.getSchema(id),这样行吗?
  • 否,将编译器错误移至该语句,该错误消息与第二个错误类似。
  • 你能把schemas的声明和schemas.getSchema(id)的实现(或至少方法签名)吗?
  • 是的,当然,我只是在包装一个模式注册表库。试图减少原始帖子中的噪音 - 签名只是fun getSchema(id: Int): Schema.RecordSchema。

标签: scala jvm kotlin scalac


【解决方案1】:

看起来 Kotlin 为这种情况生成了不同数量的类。我编译了 Java 和 Kotlin 的源代码,发现 Java 有额外的文件 ParentSealedJava$1.class。 Java 和 Kotlin 中 Parent 和 Sealed 类的字节码几乎相同(我使用 javap -c 检查字节码),所以我认为 Scala 编译器在某种程度上依赖于 Kotlin 中这个缺失的文件。

【讨论】:

  • 是的,不确定这是 Kotlin 还是 Scala 中的错误,还是两者都有,但最终这看起来像是一个错误。已提交给 Scala 和 Kotlin 团队 - 我们将看看修复是否成功。
  • 由于 Kotlin 类在 Java 中工作,我认为这是 scalac 中的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-23
  • 1970-01-01
  • 1970-01-01
  • 2023-01-18
  • 1970-01-01
相关资源
最近更新 更多