Kotlin 中有一些特殊类型:Any
、Unit
和 Nothing
,了解这些类型及其特征对于编写干净简洁的 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 个方法:equals
,hashCode
,toString
,所有三个函数都可以在任何类中重写。
示例:
// 在集合中保存不同类型的数据
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 的 Any
、Unit
和 Nothing
类型提供了不同的功能,Any 类型的灵活性允许变量保存任何类型的值,Unit 类型表示缺少有意义的值,通常用作没有特定结果的函数的返回类型,Nothing 类型用于处理异常情况。