ZetCode

Kotlin 是关键字

最后修改于 2025 年 4 月 19 日

Kotlin 的类型检查系统提供了强大的方法来在运行时验证对象类型。is 关键字是类型检查操作的核心。本教程深入探讨了 is 关键字,并提供了实际例子。

基本定义

Kotlin 中的 is 关键字检查一个对象是否为特定类型。如果对象与该类型匹配,则返回 true,否则返回 false。与智能转换一起使用时,它可以在范围内实现自动类型转换。

基本类型检查

is 的最简单用法是检查一个对象是否为某种类型。这在处理 Any 等泛型类型时很有用。

BasicCheck.kt
package com.zetcode

fun main() {

    val obj: Any = "Hello Kotlin"
    
    if (obj is String) {
        println("It's a String")
    } else {
        println("It's not a String")
    }
}

在这里,我们检查 obj 是否为 String。is 运算符返回 true,因此第一个分支执行。这是 Kotlin 中类型检查最直接的用法。

智能转换

Kotlin 的智能转换在类型检查后自动转换对象。在 is 返回 true 的范围内,该对象被视为该类型。

SmartCast.kt
package com.zetcode

fun printLength(obj: Any) {
    if (obj is String) {
        println(obj.length) // Smart cast to String
    }
}

fun main() {

    printLength("Kotlin") // Output: 6
    printLength(123) // No output
}

在检查 obj is String 之后,Kotlin 会自动将 obj 视为 String,在 if 块内。我们可以直接调用 String 方法,比如 length,而无需显式转换。

使用 !is 的否定检查

!is 运算符是 is 的否定。它检查一个对象是否不是某种类型。智能转换也适用于否定检查。

NegativeCheck.kt
package com.zetcode

fun processValue(value: Any) {
    if (value !is String) {
        println("Not a string: $value")
    } else {
        println(value.uppercase())
    }
}

fun main() {

    processValue(42) // Output: Not a string: 42
    processValue("hello") // Output: HELLO
}

!is 运算符检查 value 是否不是 String。在 else 分支中,value 被智能转换为 String,允许我们调用 uppercase()。

使用 is 的 When 表达式

is 关键字与 when 表达式配合良好。这允许对多个可能类型进行清晰的模式匹配。

WhenCheck.kt
package com.zetcode

fun describe(obj: Any): String = when (obj) {
    is String -> "String with length ${obj.length}"
    is Int -> "Integer with value $obj"
    is Double -> "Double with value $obj"
    else -> "Unknown type"
}

fun main() {

    println(describe("Kotlin")) // Output: String with length 6
    println(describe(42)) // Output: Integer with value 42
    println(describe(3.14)) // Output: Double with value 3.14
}

when 表达式使用 is 检查 obj 的类型。每个分支都会自动智能转换为已检查的类型,从而允许特定于类型的操作。这是 if-else 链的清晰替代方案。

检查泛型类型

使用具体化类型参数,您可以在运行时检查泛型类型。这扩展了 is 功能以进行泛型类型检查。

GenericCheck.kt
package com.zetcode

inline fun <reified T> checkType(obj: Any) {
    if (obj is T) {
        println("Object is of type ${T::class.simpleName}")
    } else {
        println("Object is not of type ${T::class.simpleName}")
    }
}

fun main() {

    checkType<String>("Hello") // Output: Object is of type String
    checkType<Int>("World") // Output: Object is not of type Int
}

具体化类型参数在运行时保留类型信息。这允许 is 针对泛型类型 T 进行检查。如果没有具体化,由于类型擦除,这种检查将无法实现。

检查密封类

is 关键字对于密封类特别有用。它允许以类型安全的方式对所有可能的子类型进行详尽的检查。

SealedCheck.kt
package com.zetcode

sealed class Result
class Success(val data: String) : Result()
class Error(val message: String) : Result()

fun handleResult(result: Result) {
    when (result) {
        is Success -> println("Success: ${result.data}")
        is Error -> println("Error: ${result.message}")
    }
}

fun main() {

    handleResult(Success("Data loaded")) // Output: Success: Data loaded
    handleResult(Error("Network error")) // Output: Error: Network error
}

密封类确保所有可能的子类型都是已知的。带有 is 检查的 when 表达式提供了详尽的处理。每个分支都智能转换为特定的子类型,从而允许访问子类型属性。

检查可空类型

is 运算符可以优雅地处理可空类型。它可以在一个操作中检查对象的类型和空状态。

NullableCheck.kt
package com.zetcode

fun checkNullable(value: Any?) {
    if (value is String?) {
        println("It's a nullable String")
    }
    
    if (value is String) {
        println("It's a non-null String: $value")
    } else if (value == null) {
        println("It's null")
    }
}

fun main() {

    checkNullable("Hello") // Output: It's a nullable String + non-null String
    checkNullable(null) // Output: It's a nullable String + It's null
}

第一个检查使用 String? 匹配 String 和 null。第二个检查使用 String 仅匹配非空字符串。这表明 is 如何区分可空类型和非空类型。

类型检查的最佳实践

来源

Kotlin 类型检查和转换文档

本教程深入介绍了 Kotlin 的 is 关键字,展示了其在类型检查中的用法,并启用了智能转换。我们探讨了各种场景,包括密封类、泛型和可空类型。正确使用类型检查可以使您的代码更加健壮和类型安全。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有多年的编程经验。自 2007 年以来,我一直在撰写编程文章。到目前为止,我撰写了 1400 多篇文章和 8 本电子书。我有超过八年的编程教学经验。

列出 所有 Kotlin 教程