Kotlin类型系统笔记
存在String,其实不存在String?这个类,这是编译器做的功课。所以?可空类型的类型系统是隐含的。
Unit也是被编译器特殊对待的,Unit作为函数返回值的话,可以不用显式返回。
Unit 和 Nothing 填补了原本 Java 当中的类型系统,让 Kotlin 的类型系统更加全面,也让大部分的“语句”可以当作“表达式”来用。
子类是从父类继承属性和方法的一个类,而继承则是实现这种子类和父类之间的关系的一种方式,它只是一种方式。String和String?是父子类关系,但不是用继承来实现的,而是靠编译器。
从Java过来Kotlin,会有一种思维,以Java的眼光来看Kotlin的类型系统,去想这个Kotlin类在Java中代表了什么。
现在我认为这是不必要的。Kotlin的抽象性,新的类型系统正是让开发者更好地写代码。它们之间的对照关系、翻译关系,了解即可。写代码时要想着Kotlin的类型系统。
Any
Any?可以看作Any的父类,虽然它们之间没有继承关系。在Kotlin基于JVM系统中,Any
会被翻译为Object
并根据有无“?”来加上 @Nullable
或 @NotNull
。
在Kotlin类型系统中,Any是所有类型的 super class,而Any?也可以看作 Any 的父类。
Unit
Unit类在Kotlin中是一个单例。
1 | public object Unit { |
它的作用主要是
- 特殊的编译器处理。返回值为
Unit
不用显式返回。不用写return
- 方便构建 函数式编程。让 () -> Unit 这种函数类型成为可能。
Unit?
没有什么应用场景,而且使用它还消除了 隐式return 的功能,要显式写return了。
Nothing
Nothing
类是所有类型的子类,Nothing 的概念与“Any?”恰好相反。“Any?”是所有的 Kotlin 类型的父类,Nothing 则是所有类型的子类。像 Nothing 这样的概念,在函数式编程当中,也被叫做底类型(Bottom Type),因为它位于整个类型体系的最底部。
1 | public class Nothing private constructor() |
可以看到,Nothing
的构造函数是私有的。目前据我了解,返回 Nothing
的表达式只有 报错相关 的。
比如
1 | fun calculate(): Nothing = throw NotImplementedError() |
所以 Nothing
帮助编译器进行函数流程的判断,一般返回了Nothing
的表达式后面的代码都不会执行。
作为返回值
指示函数永远不会正常返回,因为里面有报错语句。
1 | fun calculate(): Nothing { |
作为函数参数
指示该函数永远不能使用,因为无法构造 Nothing
。
1 | // 这是一个无法调用的函数,因为找不到合适的参数 |
Nothing?
没有想到什么应用场景。