热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Kotlin类型系统竟如此简单

这篇文章主要给大家介绍了关于Kotlin类型系统的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Kotlin具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

Quote

在学习 Kotlin 的过程中,对 Kotlin 的类型系统产生了好奇,Kotlin 是否存在类似于 Java 中 Object 的公共基类?Kotlin 中是否也有类似于 Java 基础类型这样的单独分支?在研究一番过后,博主发现相较于 Java,Kotlin 交出了更为满意的答案,而且出乎意外地简单,只需要遵循简单的规则,便能理解整个类型系统。

Any

Any 等同于 Java 中的 Object 的概念,Any 在注释中这么写到:

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

我们来简单验证下 Any 是一切的基类。

class Fruit
fun main(args: Array) {
println(Fruit() is Any)
}

在上面的代码中,我们新建了一个类,然后构造它的实例,看它是否为 Any,答案显而易见地为 true。

我们在看一些 kotlin 中的基础类型,也就是 Int、Double、Float、Byte 等等的父类是否也是 Any。

println(3.233F is Any)
println(2 is Any)

答案也是true。这里额外地解释下,Kotlin 并没有 Java 中基础类型和封装类型差异化处理,也没有拆箱和装箱的处理。基础类型就是基础类型,但它们也以Any作为父类。

Unit

再来看看 Unit 这个 Kotlin 中的特殊东西。

/**
* The type with only one value: the `Unit` object. 
* This type corresponds to the `void` type in Java.
*/
public object Unit {
override fun toString() = "kotlin.Unit"
}

在 kotlin 中每个函数一定是有返回值的。

这里说明一下概念,也将会在后续的章节里面再次提到。kotlin 为了这个一定有返回值这个概念,做了很多工作,但好处是非常明显的,我们能够以统一的视角来看待 kotlin 的函数。

Unit 这个概念表征着什么都不做,但什么都不做确实也是一种返回值。如果我们不做任何声明,函数的返回值就是 Unit,表明我返回了一个什么都没做的东西。

我们来验证一下,声明一个空函数,然后打印它。(在 Java 中会编译不过)

fun justReturn() {
}

fun main(args: Array) {
print(justReturn())
}

结果输出了kotlin.Unit,证明了返回值就是 Unit。

那么这里有一个疑问,就是 Unit 和 Any 什么关系?我们通过 is 关键字来看看。

fun main(args: Array) {
print(justReturn() is Any)
}

恩恩,Unit 也是 Any 的子类!

Nothing

我们继续延展下kotlin 中每个函数一定是有返回值的这个概念。前面我们看的是正常返回的情况,那如果程序发生异常,也会有返回值吗?kotlin 对于这种情况,也是延续了一定有返回值这种概念。这个返回值叫做 - Nothing!

Nothing 意味着不可达,程序实际运行时不会产生任何一个 Nothing 类型对象,啥?!这怎么理解。kotlin 一旦发现返回了 Nothing,会保证后面的代码不再执行。

所以 Nothing 常用于 throw 这样异常退出的情况,这样后续的代码就不会被执行。我们看看 kotlin 中自身的例子。

/**
* Terminates the currently running process.
*
* @param status serves as a status code; by convention,
* a nonzero status code indicates abnormal termination.
*
* @return This method never returns normally.
*/
@kotlin.internal.InlineOnly
public inline fun exitProcess(status: Int): Nothing {
System.exit(status)
throw RuntimeException("System.exit returned normally, while it was supposed to halt JVM.")
}

注意啦,我们再看看 Nothing 在类型系统中的位置。Nothing 与 Any 相反,是一切类型的子类!也就是说 Nothing,是 Fruit、是 School、是 Money、也是 Any。Nothing 意味着不可达的状态,每一种类型都包含这种不可达的状态,因而这种状态 Nothing,是这些的子类。

注意上图中 Nothing 所处的位置。

Nullable

kotlin 的一大杀手锏就是这个可空类型,一种类型后面加上?,这种类型就可以为空了。我们来看看引入可空类型过后,类型系统是怎样的。

1、首先看看普通类和可空类型之间的关系。

class Fruit
fun main(args: Array) {
print(Fruit() is Fruit?)
}

答案是true,这里很好理解,两者之间的区别在于是否可以为空,可以为空的自然而然是基类,不可为空的是可以为空下的一种派生。

2、Any 是否有可空类型

kotlin 最让人欣赏的地方在于一个概念贯彻到底。Any 在 kotlin 中也是有可空类型的。感官上 Any? 是 Any 的父类,Any 是不可空类型的父类,所以 Any? 也是不可空类型的父类吗?答案就是这样的,我们来验证下。

class Fruit
fun main(args: Array) {
print(Fruit() is Any?)
}

3、Unit 是否有可空类型

是的,Unit 也有空类型 Unit?。但这是一个难理解的概念,其本身包含了两个值 Unit 和 null。这是 kotlin 为了延续统一的概念,很少会有场景使用到,但咱们得清楚。

4、Nothing 是否有可空类型

Nothing 当然也有可空类型 Nothing?,其本身有且仅有一个值 null,也就是说其就是 null。Nothing 本身不可达,不会有任何一个实例,那就只能是 null 了。

我们来验证一下

fun main(args: Array) {
println(null is Nothing)
println(null is Nothing?)
println(null is Any)
println(null is Any?)
}

分别是 false、true、false 和 true。

总结

这里借用下 natpryce 的图,大家看一下这张图,这就是 kotlin 的类型系统。

咱们只需要理解一下几点,就完全弄明白 kotlin 类型系统。

  • Any 和 Nothing 分别是所有对象的基类和子类。
  • 可空类型是不可空类型的父类。

当我们不清楚类型时,对照上面两个概念就能明白。

参考

  • Mistaeks I Hav Made: A Whirlwind Tour of the Kotlin Type Hierarchy
  • https://proandroiddev.com/nothing-else-matters-in-kotlin-994a9ef106fc

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。


推荐阅读
  • python基础(二、pycharm安装、卸载)
    3.在Ubuntu中安装PyCharmPyCharm的官方网站地址是:https:www.jetbrains.compycharm注意:安装时不要使用root用户安装,否则后期使用 ... [详细]
  • 本文分析和介绍了GLo ... [详细]
  • Mac下Flutter安装AndroidStudio配置
    补一个Mac下Flutter安装AndroidStudio配置(官网地址:https:flutter.devdocsget-startedinstallmacos)1.下载安装包; ... [详细]
  • 自动化部署服务——AWS CodeDeploy 快速入门
    https:amazonaws-china.comcnblogschinagetting-started-with-codedeploy作为DevOps和微服务的深入践行者 ... [详细]
  • Android性能优化检测App卡顿
    在移动APP性能评测-流畅度评测中,我们介绍了如何准确客观评价APP的流畅度,最终采用SM指标来评价应用的流畅度,在知道如何评价流畅度之后 ... [详细]
  • 代码:在mysql5.6,运行正常,5.7报错SELECTsum((selecta.numwherea.status1))astotalFROMmes_order_productA ... [详细]
  • 2019.4.14第1001题:SumProblemProblemDescriptionHey,welcometoHDOJ(HangzhouDianziUniversityOnli ... [详细]
  • Git(1)
    安装Git完毕(在开始菜单打开的话,打开的不是你想要的路径,切换路径很麻烦)1.D盘新建GitTest文件夹2.打开GitTest,在空白的地方右键,3.单击GitBashHere ... [详细]
  • 在Android源码环境下编译系统App使用第三方jar包的方法(备忘)
    1将要使用的jar包放入App的根目录,即Android.mk所在目录2按如下方式编写Android.mk文件(########之间的行用于编译和使用jar包)LOCAL_PATH:$(ca ... [详细]
  • 这一篇主要总结一下jQuery这个js在引入的时候做的一些初始化工作第一句window.undefinedwindow.undefined;是为了兼容低版本的IE而写的因为在低版本 ... [详细]
  • spotify engineering culture part 1
    原文,因为原视频说的太快太长,又没有字幕,于是借助youtube,把原文听&打出来了。中文版日后有时间再翻译。oneofthebigsucceessfactorshereatSpo ... [详细]
  • MyBatis模糊查询和多条件查询一、ISmbmsUserDao层根据姓名模糊查询publicListgetUser();多条件查询publicList ... [详细]
  • 载波|等份_NR SRS时频域位置
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了NRSRS时频域位置相关的知识,希望对你有一定的参考价值。微信同步更新欢迎关注同名modem协议笔记S ... [详细]
  • vscode里的html标签导航的一系列问题
    哈喽,我今天带来的经验是,vscode在18年10月更新后的1.29以后,编辑html文档时,会发现最上面有个类似于HTML标签导航的玩意儿,可能部分同学和我一样不习惯用它们,现在 ... [详细]
  • Android Rxbus事件总线
    我的视频课程:《FFmpeg打造Android万能音频播放器》最近在项目中使用了Rxjava和RxAndroid,确实感觉挺不错的,然后听说可以用RxBus来替换 ... [详细]
author-avatar
BELLICOSE牛仔
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有