Kotlin 作为 Android 开发首选语言,在新的项目中也使用了,确实比较简洁,本篇文章就详细介绍一下 Koltin 开发所需要的必会语法知识。主要介绍的有变量、数据类型、函数、表达式、循环语句、异常。
一、变量 & 常量
1.1 变量
学习任何语言,可能一开始学习的就是如何定义一个变量,又如何定义一个常量。
在 Java 中定义一个变量:
int a = 10;
在 kotlin 中定义一个变量:
var a:Int = 10
从写法中看出几点区别:
- kotlin 中使用
var
关键字定义一个变量。 - 类型和变量名位置互换。
- 变量名和类型之间用冒号隔开。
- kotlin 不需要分号。
1.2 空类型安全
在上面的代码中,我们定义变量的同时,给变量赋了初值,但是在 Kotlin 中,如果你声明一个变量,但是没有赋初值,那是不行的:
//这种写法AS会报错:Property must be initialized
var a:Int
对于 AS 的报错信息,说的是 属性需要在声明的同时初始化
。这里就需要提到 Kotlin 的空安全设计–> 通过 IDE 的提示来避免调用 null 对象,避免 NullPointerException 这个最为常见的异常。在 Kotlin 中,所有变量默认都是不允许为空的,如果你认为这个变量可为空,需要这样写:
var a:String? = null
这种在类型后面加 ?
的写法,在 Kotlin 中叫 可空类型
,对于可空类型的变量,你在使用时,需要对此变量再做一次非空确认后再调用方法。
举个简单的例子,你定义了一个可空类型的 TextView,想调用 TextView 的 setBackgroundColor() 方法,需要这么写:
var view: TextView? = null
view?.setBackgroundColor(Color.BLACK)
在开发的实际过程中,可能我确定自己调用对象的方法时,此对象一定不会为空,编译器不需要替我检查,那么可以这样写:
view!!.setBackgroundColor(Color.BLACK)
使用双感叹号,表示确定调用方法时,对象不为空,这样写后,编译器就不检查了,后果由开发者承担。
其实对于 Kotlin 的空安全,只要关注使用时是否为空即可。想要变量为空,加?.
,调用时再次确认,加?.
,如果不需要编译器检查,就使用!!.
可能有些人认为这很麻烦,但是这样做,能尽量避免空指针,但是也有另外一种办法,就是延迟初始化,使用 lateinit
关键字:
lateinit var view: TextView
使用延迟初始化的变量,就是告诉编译器这个变量,我现在暂时没法初始化,但是我在使用它时,一定会初始化,编译器不需要检查了。
1.3 常量
在 Java 中,定义一个常量:
final String a = "Hello";
在 Kotlin 中,定义一个常量:
val a = "Hello"
使用 val
关键字的变量,又叫做只读变量,只能赋值一次,无法修改。
二、数据类型 & 类型判断
2.1 数据类型
Kotlin 中使用的基本类型有 布尔型(Boolean
)、数值型(Int
、Long
、double
、 Float
、 Short
、Byte
)、字符型(Char
)、字符串(String
)、数组(Array
)这几种。
2.2 装箱拆箱
在 Java 中,int 类型,自动装箱会是 Integer 类型。而在 Kotlin 中,只有 Int 类型,这类似于 Java 中 int 类型和 Integer 类型的混合,编译器会自动判断此变量需要的是 int 类型,还是 Integer 类型,无需开发者担心,这点上,Kotlin 做的还是很良心的。正常情况下,如果满足定义的变量是不可空类型或者是数组类型,就不会自动装箱。
2.3 类型推断
在声明变量的时候,可以不写类型,因为 Kotlin 有类型推断,这个还是很方便的,例如:
var a = 10
2.4 数组
Kotlin 中数组的写法也与 Java 中数组的写法有所区别。
在 Java 中定义一个数组,写法是这样的:
int[] array = new int[]{1,2,3};
在 Kotlin 中定义一个数组,写法确是这样的:
var array:IntArray = intArrayOf(1,2,3)
2.5 字符串
Kotlin 中字符串的写法与 Java 类似,但是多一个比较好用的符号$
:美元符号,也就是字符串模板,例如这样:
val a = 10
val b = 10
print("a+b 的值是 ${a+b}")
同时,在Kotlin 中字符串的比较也是很常见的,如果比较内容,使用==
,类似于 Java 中的 equals,如果是比较对象的引用值,使用 ===
,类似于 Java 中的 ==,比较的是对象是否相等。
在 Kotlin 中,还有一个原始字符串的概念,不过一般不用,用法是使用三个双引号表示,对于引号内的内容,会原模原样的输出显示。
2.6 区间
在 Kotlin 中,有一个 Java 没有的概念–>区间。用法也很简单,一看便知:
val range:IntRange = 0..1024 //[0.1024]
val range_exclusive:IntRange = 0 until 1024 // [0,1024)
三、函数
说完了 变量常量,数据类型,下面该说一说函数了,有句话不是这样说的吗,“得函数者的天下”,如果说变量是用来存储数据的,那么函数就是处理数据的。
3.1 声明
先来看一下在 Java 中如何声明一个函数:
String getName(String name){
return name;
}
那么在 Kotlin 中如何声明一个函数呢:
fun getName(name:String):String{
return name
}
从中可以看到几点区别:
- 以
fun
关键字开头。 - 返回值写在了函数和参数的后面
看到这里,可能就有人问了,如果函数没有返回值该如何写呢,例如在 Java 中,主函数是这样的:
void main(){
}
那么在 kotlin 中主函数是怎么写的呢:
fun main(){
}
咦,怎么没看到返回值呀,其实在 Kotlin 中没有返回值的函数,返回的是 Unit,但是这个可以省略,其实是这样的:
//没有返回值的函数中的 Unit 可以省略
fun main():Unit{
}
结合一下前面说的变量的可空类型,那么对于需要传递参数的函数来说,参数也是有可空的控制的,举个例子:
var name:String? = "小命"
fun getName(name:String?):String{
return name
}
fun main(){
getName(name)
}
上面的写法是正确的,错误的写法有:可空变量传给不可空参数,报错。总结下来就是:
- 可空传可空,不可空传不可空,不报错。
- 可空传不可空,不可空传可空,报错。
对于函数体只有一行的函数,如果函数表达式的值就是函数的返回值的话,有简单的写法,例如这样:
// arg1 + arg2 的值就是你想要函数返回的值,那么都不需要写返回类型,自动推导了
fun sum(arg1:Int,arg2:Int) = arg1 + arg2
因为在 Kotlin 中,一切皆对象,所以函数也可以赋值给变量,这样的函数就没有名字了,例如这样:
var int2Long = fun (x:Int):Long{
return x.toLong()
}
3.2 具名参数 & 变长参数 & 默认函数
在 Kotlin 中,函数还有具名参数,变长参数,默认参数等,在此简单介绍一下
具名参数
//给函数的实参附上形参
fun sumT(arg1:Int,arg2:Int) = arg1 + arg2
fun main() {
sumT(arg1 = 2,arg2 = 3)
}
变长参数 & 默认参数
// 变长参数:
// 某个参数可接收多个值,可以不为最后一个参数
// 如果传参时有歧义,需要使用具名参数
fun main(vararg args: String) {
for (arg in args) {
println(arg)
}
val array = intArrayOf(10,11,12)
// Spread Operator:*array
// 只支持展开Array
// 只能用于变长参数列表的实参
// 不能重载,不算一般意义上的运算符
hello( 1.0,*array,2, 3, 4, 5, aString = "hello")
hello( ints = *array, aString = "hello")
}
// 默认参数
// 可以为任意位置的参数指定默认值
// 传参时,如果有歧义,需要使用具名参数
fun hello(double:Double = 3.0,vararg ints: Int, aString: String) {
println(double)
ints.forEach(::println)
println(aString)
}
四、表达式 & 循环语句
4.1 if 表达式
Java 中的 if 条件语句与 Kotlin 中的 if 条件语句,用法类似,只是 Kotlin 中的 if 条件表达式的结果可以赋值给一个变量,例如这样:
val max = if (a > b) {
print("Choose a")
} else {
print("Choose b")
}
可以这样使用的话,那么对于 Java 中的三元操作符,在 Kotlin 中就可以简单使用了,例如这样:
val x = 5
val c = if (x in 1..8) x else 0
4.2 when 表达式
对于 Kotlin 中的 When 表达式,它有点类似 Java 中的 if else
语句,比如这样:
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // 注意这个块
print("x 不是 1 ,也不是 2")
}
}
将 x 与分支条件顺序比较,直到满足某个分支条件。如果多个分支需要相同方式处理,可以这样写:
when (x) {
0, 1 -> print("x == 0 or x == 1")
else -> print("otherwise")
}
也类似于 switch case
语句,比如这样:
//如果不提供参数,所有的分支条件都是简单的布尔表达式,而当一个分支的条件为真时则执行该分支
when {
x.isOdd() -> print("x is odd")
x.isEven() -> print("x is even")
else -> print("x is funny")
}
同时,也可以结合区间来判断,例如:
检测一个值在不在一个区间范围内
when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}
检测一个值是或者不是一个特定类型
fun hasPrefix(x: Any) = when(x) {
// is 关键字类似于 Java 中的 instanceof 关键字
is String -> x.startsWith("prefix")
else -> false
}
when 中使用 in 运算符来判断集合内是否包含某实例
fun main(args: Array<String>) {
val items = setOf("apple", "banana", "kiwi")
when {
"orange" in items -> println("juicy")
"apple" in items -> println("apple is fine too")
}
}
4.3 循环语句
在 Java 中有 for循环、do while循环、while循环。在 Kotlin 中,对于后两者的使用方式和 Java 中一样,这边主要说一下 for 循环,有点不一样,使用如下:
fun main(args: Array<String>) {
val items = listOf("apple", "banana", "kiwi")
//写法一
for (item in items) {
println(item)
}
//写法二
for (index in items.indices) {
println("item at $index is ${items[index]}")
}
//写法三
for (indexValue in args.withIndex()){
println("${indexValue.index} -> ${indexValue.value}")
}
//写法四
for ((index, value) in items.withIndex()) {
println("the element at $index is $value")
}
}
比较常见的写法就是写法一,写法三和写法四其实是一样的。
同时,在 Java 中有关键字 break,continue,return 等关键字,在 Kotlin 中也有这些关键字,使用方法和 Java 一样,这边就不多说了。
五、异常
Kotlin 中的异常用法和 Java 中的异常用法一样,有点区别的就是 try catch
也是表达式,可以用来赋值,在此就直接贴代码了:
fun main(args:Array<String>) {
try {
val arg1 = args[0].toInt()
val arg2 = args[1].toInt()
println("$arg1 + $arg2 = ${sumN(arg1,arg2)}")
}catch (e:NumberFormatException){
println("您确定输入的是整数吗?")
}catch (e:ArrayIndexOutOfBoundsException){
println("您确定输入的是两个整数吗?")
}catch (e:Exception){
println("程序出现未知错误,可能是您的人品有问题 ${e.message}")
}finally {
println("谢谢您使用我们的加法计算器")
}
// try catch 也是表达式,可以用来赋值
val result = try {
args[0].toInt() / args[1].toInt()
}catch (e:Exception){
e.printStackTrace()
0}
}
fun sumN(arg1:Int,arg2:Int):Int{
return arg1 + arg2
}
最后
本篇文章介绍了 Kotlin
开发中较为基础常见的知识,希望各位有所收获。 本人水平有限,如有错误,请在下方评论中指出。