首页 > 解决方案 > 有没有一种优雅的方法来检查对象的类型是否属于类型列表?

问题描述

使用字符串时,您可以检查字符串是否属于这样的字符串集:

if (a in listOf("ab", "abab")) {
    // do something
}

或者:

when (a) {
    in listOf("akshd", "sd") -> {
        // do something
    }
}

现在,让我们假设您有一个密封类:

sealed class SealedClass {
    class Subclass1 : SealedClass()
    class Subclass2 : SealedClass()
    class Subclass3 : SealedClass()
}

有一种很好的方法可以检查某个对象b是否在这些类型的子集中。如果你使用when表达式,你可以这样写:

when (b) {
    is SealedClass.Subclass1, is SealedClass.Subclass2 -> {
        // do something
    }
}

如果你想使用if表达式,事情就会变得复杂。你可以这样写:

if (b is SealedClass.Subclass1 || b is SealedClass.Subclass2) {
    // do something
}

或这个:

if (
    b::class in listOf(
        SealedClass.Subclass1::class,
        SealedClass.Subclass2::class
    )
) {
    // do something
}

上述两种解决方案都非常笨拙。if使用语句时是否有更优雅的方式来表达这样的检查?

标签: kotlin

解决方案


我不相信有办法解决这个问题。

创建自定义解决方案可能会适得其反,因为类型安全将是一个问题。如果使用了不兼容的类型,则代码将运行,但您可能会以运行时错误结束。但是,如果你is直接使用,你会得到一个编译时错误,说“不兼容的类型”。

解决这个问题的干净方法是在密封类中为此创建一个方法或属性。使用适当的命名,代码将更容易阅读。例如:

sealed class Animal {
    class Cat : Animal()
    class Dog : Animal()
    class Tiger : Animal()

    val isDomestic
        get() = this is Cat || this is Dog
}

用法:

if (animal.isDomestic) {
    // do something
}

推荐阅读