ITmob-Ly
发布于 2023-07-06 / 277 阅读
0

Kotlin 中的特殊类型:Any、Unit 和 Nothing

Kotlin-Blog

Kotlin 中有一些特殊类型:AnyUnitNothing,了解这些类型及其特征对于编写干净简洁的 Kotlin 代码至关重要。这里我们尝试了解下它们是什么、何时使用它们以及它们之间有何不同。

Any

Any 的官方文档介绍:

The root of the Kotlin class hierarchy. Every Kotlin class has Any as a superclass.

Kotlin 类层次结构的根,无论我们是否显式定义它,它都是所有类的父类。

类似于 Java 中的 Object 类是类层次结构的根(是所有类的父类)。然而,两者之间也存在一些差异。

这是源码中 Any 的定义:

/**
 * The root of the Kotlin class hierarchy. Every Kotlin class has [Any] as a superclass.
 */
public open class Any {
    /**
     * Indicates whether some other object is "equal to" this one. Implementations must fulfil the following
     * requirements:
     *
     * * Reflexive: for any non-null value `x`, `x.equals(x)` should return true.
     * * Symmetric: for any non-null values `x` and `y`, `x.equals(y)` should return true if and only if `y.equals(x)` returns true.
     * * Transitive:  for any non-null values `x`, `y`, and `z`, if `x.equals(y)` returns true and `y.equals(z)` returns true, then `x.equals(z)` should return true.
     * * Consistent:  for any non-null values `x` and `y`, multiple invocations of `x.equals(y)` consistently return true or consistently return false, provided no information used in `equals` comparisons on the objects is modified.
     * * Never equal to null: for any non-null value `x`, `x.equals(null)` should return false.
     *
     * Read more about [equality](https://kotlinlang.org/docs/reference/equality.html) in Kotlin.
     */
    public open operator fun equals(other: Any?): Boolean

    /**
     * Returns a hash code value for the object.  The general contract of `hashCode` is:
     *
     * * Whenever it is invoked on the same object more than once, the `hashCode` method must consistently return the same integer, provided no information used in `equals` comparisons on the object is modified.
     * * If two objects are equal according to the `equals()` method, then calling the `hashCode` method on each of the two objects must produce the same integer result.
     */
    public open fun hashCode(): Int

    /**
     * Returns a string representation of the object.
     */
    public open fun toString(): String
}

Any 有 3 个方法:equalshashCodetoString,所有三个函数都可以在任何类中重写。

示例:

// 在集合中保存不同类型的数据
val sampleList: List<Any> = listOf("itmob.cn", true, 88)

// 定义处理不确定类型的参数,或返回值类型未知的函数
fun sample(any: Any): Any{
    when (any) {
        is String -> //...
        is Boolean -> //...
        is Int -> //...
        else -> //..
    }

    return any //可以返回任何类型
}

Kotlin 的 Any 类型提供了保存任何类型值的灵活性,允许开发人员编写通用函数动态处理未知类型。

Unit

源码中 Unit 的定义:

/**
 * The type with only one value: the `Unit` object. This type corresponds to the `void` type in Java.
 * 只有一个值的类型:“Unit”对象。 该类型对应于Java中的“void”类型。
 */
public object Unit {
    override fun toString() = "kotlin.Unit"
}

Unit 与 Java 或 C 中的 void 相同。当函数的返回类型为 Unit 时,意味着该函数不返回任何内容。

在 Kotlin 中,函数的默认返回类型是 Unit,如果没有显式指定函数的返回值类型,那么 Kotlin 编译器将使用 Unit 作为返回值类型。

fun greeting(name: String): Unit {
    println( "Hello, $name !" )
}

greeting("https://itmob.cn")

Unit 是单例的,只是一个标记类型,用于指示值的缺失。通常用作不产生结果或不返回有意义值的函数的返回类型。
当函数的返回类型为Unit时,return关键字变为可选

Nothing

源码中 Nothing 的定义:

/**
 * Nothing has no instances. You can use Nothing to represent "a value that never exists": for example,
 * if a function has the return type of Nothing, it means that it never returns (always throws an exception).
 */
public class Nothing private constructor()

Nothing 没有用 open 关键字修饰,它是最终类(final calss)是不可扩展和非开放的,并且它的构造函数也是私有的,这意味着我们也无法创建该对象。

所以Nothing 无法实例化此类的实例,也没有其他类可以继承它,所以不能创建实例作为返回值。

我们通常使用 Nothing 作为函数的返回类型来表明该函数总是抛出异常。

Nothing 最直观的示例是源码中 TODO 函数的实现:

/**
 * Always throws [NotImplementedError] stating that operation is not implemented.
 */

@kotlin.internal.InlineOnly
public inline fun TODO(): Nothing = throw NotImplementedError()

/**
 * Always throws [NotImplementedError] stating that operation is not implemented.
 *
 * @param reason a string explaining why the implementation is missing.
 */
@kotlin.internal.InlineOnly
public inline fun TODO(reason: String): Nothing = throw NotImplementedError("An operation is not implemented: $reason")

执行 TODO 方法就抛出异常提示其还未实现。

总结

Kotlin 的 AnyUnitNothing 类型提供了不同的功能,Any 类型的灵活性允许变量保存任何类型的值,Unit 类型表示缺少有意义的值,通常用作没有特定结果的函数的返回类型,Nothing 类型用于处理异常情况。