Kotlin基础篇——从类型系统开始

Kotlin 系列 学习笔记——第一篇

对于一门静态编程语言,其类型系统中隐藏了很多设计思路。 Kotlin 这门需要跟 Java 对比学习的语言就更能体现这一点。把类型系统当做 Java 转 Kotlin 的第一站对后续的学习还挺有帮助的,要是没学过 Java 的话……应该也不会想学 Kotlin 吧。

前提:创建变量

由于类型推导系统的存在,Kotlin 中创建变量并不都需要声明类型,只要能推导出就好。而为了更好的支持函数式编程,Kotlin 中明确区分了可变变量(variable)和不可变变量(value),分别用 varval 来创建。

Java 中可以用 final 修饰符表示不可变变量,可能因为写法比较麻烦,除了必要的地方很少出现不可变变量。Kotlin 中两种方式一样好写,就会引导人从场景方面考虑 valvar 哪个更合适。为了更好的可读性,应该尽可能减少 var 的使用,因为可以随意改变意味着每次该变量出现都需要考虑当时的值是什么,而且经常出现不可预测的值。

Java 的基本数据类型

在 Java 中,基本数据类型和引用数据类型是明确区分的,基本数据类型是 Java 中脱离了面向对象的一部分,也因此提高了运行效率。而基本数据类型又都对应着一个包装类型(属于引用数据类型),提供了面向对象的思路。

在 Kotlin 中就不存在这种基本数据类型了,看起来像是只保留了包装类型。实际上在编译过程中,只有真正需要使用包装类型的才会编译成引用数据类型,并不会影响代码执行的效率。

val a: Int = 128
val b: Int = 666

val sum = a + b

// 这种纯粹的数字编译后跟 Java 中的 int 是一样的
复制代码
特殊类型

特殊的数据类型有三个:UnitAnyNothing

Unit:意义上相当于 Java 中的 void,定义函数不需要返回值的时候,就可以返回Unit(省略不写就默认返回Unit了)。实际上 Unit 和 void 还是有区别的,Unit 是一种真实类型,它有唯一的 隐式 取值 Unit。《Kotlin实战》中写了这种设计在泛型中的应用和优势,

Any:Any 相当于 Java 中的 Object 类,是所有类的爸爸。但需要注意的是 Any 只有 toStringequalshashCode函数而不能使用 waitnotify方法,如果有需要的话可以把 Any 转换为 Java 的 Object 类再操作。

Nothing:这是一个函数的返回值类型,只在函数声明的时候会用到,表示这个函数不会 return。比如一定会抛出异常或者一定是死循环的函数。虽然不是强制的,但知道不会return任何内容对类型推导是有意义的:

这里如果 error 函数的返回值不写明 Nothing 会被认为是 Unit ,user 的类型就会被推导为 Any ,因为 ?: 前后的类型不一致。

可空类型 (?)

空安全是 Kotlin 的巨大优势之一,有效减少 NPE 也是很多人选择 Kotlin 的原因。空安全的核心就是对类型是否可空的区分,在 Java 中,String 类型的取值可能是 String 或 null,于是每次调用 String 的方法时都可能发生 NPE。这看起来并不合理,因为 null 值只能用来比较而没有 String 的特性,却披着 String 的外皮,还要在运行时才告诉我他不是 String。

Kotlin 用类型 + ? 来表示可空类型,有一种对此类型有疑问的感觉,还挺容易接受的。直观点表示:

String? = String + null

不可空类型无法被赋值为 null ,在编译期就能处理掉一大部分的 NPE 了。

除了定义变量,可空类型调用函数时也要用到 ?

a?.fun() = if(a != null){ a.fun() }

比起 Java 中层出不穷的非空判断,这样的写法优势很大,尤其是在嵌套的缩进里面,层次越少可读性越强。如果很确定该类型是非空的,或者需要看到这个 NPE (不会有人想看吧…),可以使用 !!. 强制调用函数。Kotlin 用了两个感叹号来描述这种行为,表明代码中最好不要出现这种写法。

Java 中的 if(a != null) 还可能有 else 的处理,在 Kotlin 的简化写法中可以通过 ?: 可以实现。a?:b的含义是当 a 为空时,取 b。a?.fun() 在 a 为 null 的情况下整个表达式的值为 null,结合起来就是这样的:result = a?.fun()?:b

这一行的代码的表现力很强,简直是多重嵌套的救星。

还有一种情况,就是函数接受的参数为不可空类型,而你需要对一个可空类型的数据做判断,除了用 if 判断,还可以使用 let 函数。let 函数的原理就等写到函数的时候再深入,这里只说怎么用,下面的两种写法是等价的:

集合的可变性

集合系统是比较复杂的,Kotlin 并没有完全实现一套自己的集合系统,而是在 Java 集合的基础上进行了扩展。这样可以和 Java 有更好的互操作性,同时也能比 Java 集合更加好用。集合的内容很多,这里只说一点:不可变集合。

Java 中的集合基础是 Collection 接口,其中包含add, removeclear等方法,即所有的集合都是可变的。Kotlin 中添加了不可变集合的概念,就相当于增加了一些类型。在创建集合的时候也需要想清楚是否需要可变性,以选择合适的集合类型。

乱入一个充满灵性的插图:

可以看出 List 是不可变的,ArrayList 是可变的:

Kotlin 的第一篇学习笔记就是这些内容了,最初总想着记得详细一些,但笔记毕竟还不是教程,我也的确没有做教程的水平。这种笔记更适合在有一定基础的情况下阅读,利用碎片时间积累更多知识,如果有人觉得读完文章有所收获就再好不过了。

学习资料还是推荐官方文档以及《Kotlin实战》,相关的代码实在太简单了,就不上传 Github 了。最近工作比较忙,下一篇随缘吧……(?点赞评论可以增加缘分值哦)

转载于:https://juejin.im/post/5a709f48f265da3e53427e90

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值