这是我参与「第四届青训营 」笔记创作活动的第3天
KOTLIN
简介
Google在2017年的I/O大会上宣布,Kotlin正式成为 Android的一级开发语言,和Java平起平坐,Android Studio也对Kotlin进行了全面的支持。 两年之后,Google又在2019年的I/O大会上宣布,Kotlin已经成为Android的第一开发语言, 虽然Java仍然可以继续使用,但Google更加推荐开发者使用Kotlin来编写Android应用程序, 并且未来提供的官方API也将会优先考虑Kotlin版本。Android官 网文档的代码已优先显示Kotlin版本,官方的视频教程以及Google的一些开源项目,也改用了 Kotlin来实现。 Kotlin是由 JetBrains公司开发与设计的,Kotlin的语法更加简洁,对于同样的功能,使用Kotlin开发的代码量可能会比使用Java开发的减少50% 甚至更多。另外,Kotlin的语法更加高级,相比于Java比较 老旧的语法,Kotlin增加了很多现代高级语言的语法特性,使得开发效率大大提升。还有, Kotlin在语言安全性方面下了很多工夫,几乎杜绝了空指针这个全球崩溃率最高的异常,至于是 如何做到的,我们在稍后就会学到。 然而Kotlin在拥有众多出色的特性之外,还有一个最为重要的特性,那就是它和Java是100%兼 容的。Kotlin可以直接调用使用Java编写的代码,也可以无缝使用Java第三方的开源库。这使得Kotlin在加入了诸多新特性的同时,还继承了Java的全部财富。
环境
有两种选择:
- IDEA,由于是JetBrains公司自己的产品,可以完美支持Kotlin,不过JetBrains的产品都比较吃内存
- 可以考虑在线环境学习,是JetBrains公司所提供的。这里是网址
- 使用Android Studio,遗憾的是,Android Studio作为一个专门用于开发 Android应用程序的工具,只能创建Android项目,不能创建Kotlin项目。但是没有关系,我们可以随便打开一个Android项目,在里面编写一个Kotlin的main()函数,就可以独立运行 Kotlin代码了。
KT入门
Hello world!
fun main() {
println("Hello, world!!!")
}
变量
而Kotlin中定义一个变量,只允许在变量前声明两种关键字:val和 var。 val(value的简写)用来声明一个不可变的变量,这种变量在初始赋值之后就再也不能重新赋 值,对应Java中的final变量。 var(variable的简写)用来声明一个可变的变量,这种变量在初始赋值之后仍然可以再被重新赋值,对应Java中的非final变量。
Kotlin拥有出色的类型推导机制。
Kotlin句尾不需要加分号,这一点上与很多编程语言类似。
Kotlin的类型推导机制并不总是可以正常工作的, 比如说如果我们对一个变量延迟赋值的 话,Kotlin就无法自动推导它的类型了。这时候就需要显式地声明变量类型才行,Kotlin提供了 对这一功能的支持,语法如下所示:
val a: Int = 10
Kotlin完全抛弃了Java中的 基本数据类型,全部使用了对象数据类型。在Java中int是关键字,而在Kotlin中Int变成了一 个类,它拥有自己的方法和继承结构。
Java和Kotlin数据类型对照表
| Java基本数据类型 | Kotlin对象数据类型 | 数据类型说明 |
|---|---|---|
| int | Int | 整型 |
| long | Long | 长整型 |
| short | Short | 短整型 |
| float | Float | 单精度浮点型 |
| double | Double | 双精度浮点型 |
| boolean | Boolean | 布尔型 |
| char | Char | 字符型 |
| byte | Byte | 字节型 |
下面给出一个简单的程序例子:
fun main() {
var a: Int = 10
a = a * 10
println("a = " + a)
}
注意,如果这里使用val会报错,因为val是不可变的数据类型
关于val关键字:Kotlin之所以这样设计,是为了解决Java中final关键字没有被 合理使用的问题。 在Java中,除非你主动在变量前声明了final关键字,否则这个变量就是可变的。然而这并不 是一件好事,当项目变得越来越复杂,参与开发的人越来越多时,你永远不知道一个可变的变 量会在什么时候被谁给修改了,即使它原本不应该被修改,这就经常会导致出现一些很难排查的问题。因此,一个好的编程习惯是,除非一个变量明确允许被修改,否则都应该给它加上final关键字。 但是,不是每个人都能养成这种良好的编程习惯。很多Java程序员没有主动在变量前加上final关键字的意识,仅仅因为Java对此是不强制的。因此,Kotlin在设计的时候就 采用了和Java完全不同的方式,提供了val和var这两个关键字,必须由开发者主动声明该变量 是可变的还是不可变的。 那么我们应该什么时候使用val,什么时候使用var呢?这里我告诉你一个小诀窍,就是永远优 先使用val来声明一个变量,而当val没有办法满足你的需求时再使用var。这样设计出来的程序会更加健壮,也更加符合高质量的编码规范。
函数
定义函数的语法如下:
fun methodName(param1: Int, param2: Int): Int {
return 0
}
首先fun(function的简写)是定义函数的关键字,无论定义什么函数,都一定要使用fun来声明。 紧跟在fun后面的是函数名,良好的编程习惯是函数名最好要有一定的意义,能表达这个函数的作用是什么。 函数名后面紧跟着一对括号,里面可以声明该函数接收什么参数,参数的数量可以是任意多个,例如上述示例就表示该函数接收两个Int类型的参数。参数的声明格式是“参数名: 参数类型”,其中参数名也是可以随便定义的,这一点和函数名类似。如果不想接收任何参数,那么写 一对空括号就可以了。 参数括号后面的那部分是可选的,用于声明该函数会返回什么类型的数据,上述示例就表示该函数会返回一个Int类型的数据。如果你的函数不需要返回任何数据,这部分可以直接不写。 最后两个大括号之间的内容就是函数体了,我们可以在这里编写一个函数的具体逻辑。由于上述示例中声明了该函数会返回一个Int类型的数据,因此在函数体中我们简单地返回了一个0。
下面给出一个例子:
import kotlin.math.max
fun main() {
val a = 37
val b = 40
val value = largerNumber(a, b)
println("larger number is " + value)
}
fun largerNumber(num1: Int, num2: Int): Int {
return max(num1, num2)
}
一个返回两个数之中最大值的函数。这里需要注意,用到了kotlin的max函数,需要导入包,如果使用Android Studio进行编写,可以通过代码补全自动导包,但通过其他IDE编写时,应该手动导入。
语法糖
当一个函数中只有一行代码时,Kotlin允许我们不必编写函数体,可以直接将唯一的一行代码写 在函数定义的尾部,中间用等号连接即可。比如我们刚才编写的largerNumber()函数就只有 一行代码,于是可以将代码简化成如下形式:
fun largerNumber(num1: Int, num2: Int): Int = max(num1, num2)
由于max()函数返回的是一个 Int值,而我们在largerNumber()函数的尾部又使用等号连接了max()函数,因此Kotlin可 以推导出largerNumber()函数返回的必然也是一个Int值,这样就不用再显式地声明返回值 类型了,代码可以进一步简化成如下形式:
fun largerNumber(num1: Int, num2: Int) = max(num1, num2)