我有一个表示字段类型的密封类:
sealed class FieldDef {
object StringField: FieldDef()
class ListField(val element: FieldDef): FieldDef()
class MapField(val children: Map<String, FieldDef>): FieldDef()
// ... more field types
}
我有一个处理两个字段定义的函数.
fun processSameTypes(fd1: FieldDef, fd2: FieldDef) {
if (fd1::class == fd2::class) {
when (fd1) {
is MapField -> processMaps(fd1, (fd2 as MapField))
is ListField -> processLists(fd1, (fd2 as ListField))
}
}
}
编写的代码是正确的-给定逻辑,fd2变量的强制转换将始终成功.
但我觉得应该有一种方法来表达这一点,而不是强制转换,但是如果我试图删除强制转换,我会得到错误:
Kotlin: Type mismatch: inferred type is FieldDef but FieldDef.ListField was expected
有没有更好的方法来处理这个问题,这样我就可以移除石膏(不需要石膏).
如果没有更好的方法解决这个问题,你能解释一下为什么编译器无法推断出fd2
变量的正确类型吗?我这里的逻辑是,由于when
受外部if
保护,并且FieldDef
是一个密封的类,编译器应该能够推断出fd2
的类型.
Kotlin版本:1.5.30(JVM)
Edit: Conclusion个
我认为公平地说,传递类对象是惯用的Java(通过其继承的Kotlin也是如此),特别是它是在运行时表示类型的方式.因此,我希望在将来看到Kotlin编译器支持它.
这就是说,它现在不支持它,所以我同意@Treffnon X的观点--接受它并加入强制转换是最好的解决方案--因此我不打算更改我的代码.
然而,我确实问过一个不使用演员阵容的方法来解决这个问题,@Sweeper提供了一个--所以我会接受这个答案.