【问题标题】:About sealed subclass of a sealed class in Kotlin关于 Kotlin 中密封类的密封子类
【发布时间】:2020-01-19 16:48:42
【问题描述】:

下面的代码可以编译,但不可能通过条件 Color.Dark 和 Color.Light 因为这两个类是抽象的。

我错过了什么吗?

sealed class Color () {
  sealed class Dark () {
    class DarkRed : Color()
    class DarkBlue : Color()
    }   
  sealed class Light {
    class LightRed : Color()
    class LightBlue : Color()
    }
}   

fun eval(c: Color) =
        when (c) {
        is Color.Dark -> println("Dark")
            is Color.Dark.DarkRed -> println("Dark Red")
            is Color.Dark.DarkBlue -> println("Dark Blue")

        is Color.Light -> println("Light")
            is Color.Light.LightRed -> println("Light Red")
            is Color.Light.LightBlue -> println("Light Blue")
}

fun main(args: Array<String>) {
    val dr = Color.Dark.DarkRed()
    eval(dr)
}

【问题讨论】:

  • 请您的 IDE 为您重新格式化整个文件。你的缩进在欺骗你。 when 语句的子句之间没有层次结构。没有“经历 Color.Dark”。
  • 我可以换个方式问这个问题:为什么这段代码可以编译?两个左缩进条件永远不会满足。
  • val i = 0; if (i == 1) { ... } 也可以编译,即使 i == 1 永远不会得到满足。编译器并不关心条件是否在运行时永远不会得到满足。它关心你的代码在语法上是否正确。
  • @JBNizet 如果您将Color.Dark 更改为String,它不会编译并出现错误Incompatible types: String and Color。并且Color.DarkColor 不兼容,就像String 一样。我认为这是一个错误。
  • @AlexeyRomanov 但是如果你用Number替换它,它会编译。我的猜测是它不能用 String 编译,因为 String 是最终的,因此 Color 无法扩展 String。但我同意 Color 也无法扩展 Number。

标签: kotlin sealed-class


【解决方案1】:

两个左缩进条件永远不会满足,因为Color.DarkColor.Light 不继承Color,而不是因为它们是抽象的。这意味着 6 个 is 分支中有 2 个是无用的,您可以放心地删除它们。但是其他4个分支(is Color.Dark.DarkRed等)经过所有Color子类,而Color是一个密封类,所以when可以不用else分支。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多