为什么Scala编译器在将Kotlin密封类传递给构造函数时会给出错误?

时间:2016-09-27 00:17:48

标签: scala jvm kotlin scalac

我有一个用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)

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

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

1 个答案:

答案 0 :(得分:0)

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