本Blog是我学习《Android第一行代码-第三版》
的学习笔记,将会不定期断更持续更新。(默认大家都和我一样学过C++或Java的基础语法)。
在Android诞生的前几年中,Java一直是Android的主要开发语言。在2017年,Google在I/O大会上宣布,Kotlin正式成为Android的一级开发语言,与Java平起平坐,同时Android Studio也对Kotlin进行了全面的支持。
2019年,Google在I/O大会上宣布,Kotlin已成为Android的第一开发语言
,Java虽然可以继续使用,但是Google更推荐开发者使用Kotlin编写Android应用程序,并且未来提供的官方API也会优先考虑Kotlin版本。
.class
文件,然后由Java虚拟机进行识别运行。不用加分号
的。在Kotlin中定义一个变量,只允许在变量前声明两种关键字:val
(value)和var
(variable)。
val
: 声明一种不可变
的变量,这种变量在初始赋值之后便不能再重新赋值,对应Java中的final变量。
var
:声明一个可变
的变量,这种变量在初始赋值之后仍可以再被重新赋值,对应Java中的非final变量。
那么就有一个疑问了,这个声明只说了该变量是可变的还是不可变的,如果知道它的数据类型呢?这就是Kotlin比较有特色的一点了,它有出色的类型推导机制(这点感觉和python有点像)。你第一次给它赋的值就是这个变量的数据类型。
假如写一个函数:
fun main() {
val a = 10
println("a = " + a)
val b = "abc"
println("b = " + b)
}
但是自动推导类型只有在初始时就赋值的情况下才会进行,如果刚开始只是声明不赋值的话,这么写就会报错。
// 错误示范
fun main() {
val a
a = 10
println("a = " + a)
}
// 正确示范
fun main() {
val a : Int
a = 10
println("a = " + a)
}
如果和学过Java的话就会发现,Java的变量名都是首字母小写的,例如:int
,double
,boolean
,char
,但是Kotlin中的变量首字母却都是大写的,例如Int
,Double
,Boolean
,Char
等等。这意味着Kotlin已经完全抛弃了Java的基本数据类型,全部使用了对象数据类型(类似于Java的String),在Java中的int
是关键字,而在Kotlin中Int
变成了一个类,它拥有自己的方法和继承结构。
原则上我们优先使用val
来声明一个变量,而当val
无法满足需求时再使用var
,这样写出来的程序会更加健壮,更加高质量。
函数是用来运行代码的载体,当调用这个函数时,这个函数里面的代码都会运行,main()
函数就是程序入口函数。
Kotlin同样允许自定义函数,语法规则如下:
fun methodName(param1 : Int,param2 : Int) : Int{
return 0
}
首先,fun
是定义函数的关键字,无论定义什么函数,都要用fun
来声明。
紧跟在fun
之后的是函数名, 这个就没什么要求了,可以根据自己喜好起任意函数名(有意义的为佳)
函数名后接一对括号,里面声明该函数接受什么参数,上述示例中就是两个Int型参数。参数的声明格式是:参数名:参数类型
,其中参数名也是可以任意定义的,如果不想接受任何参数,则保留空括号即可。
参数括号后面那部分是可选的,用于声明该函数的返回值类型,上面实例就表示函数会返回一个Int型数据。
此处还有一个Kotlin的函数的语法糖:
当函数中只有一行代码时,Kotlin函数允许我们不必编写函数体,可以直接将唯一的一行代码写在函数定义尾部,中间用等号连接即可。
fun largerNumber(num1 : Int,num2 : Int) = max(num1,num2)
程序的执行语句主要分为三种:顺序语句
,条件语句
,循环语句
顺序语句很好理解,就是程序一行一行往下执行。
条件语句主要有两种实现方式:if
和when
。
此处有一个求两个数中较大值的函数如下
fun largerNumber(num1 : Int,num2 : Int): Int{
var value = 0
if(num1 > num2)
value = num1
else value = num2
return value
}
用var
做value
的关键字是因为value
是需要修改赋值的。
Kotlin中的if语句还有一个额外的功能,就是它是可以有返回值的
。返回值就是if语句的每个条件中最后一行代码的返回值。
因此此时我们可以将上面的函数简化成如下形式:
fun largerNumber(num1 : Int,num2 : Int): Int{
val value = if(num1 > num2)
num1
else
num2
return value
}
为什么这时value
可以用关键字val
了呢?因为if语句使用每一个条件最后一行代码作为返回值,并将值直接赋给了value
变量,因此就没有重新赋值的情况了,因此就不需要var
关键字了。
其实我们可以发现这个代码还可以优化。我们最后返回的是value
,其实也就是if语句返回的值,那么我们就可以发现value
其实也是一个多余的变量,我们可以直接将if语句返回,这样代码会更精简:
fun largerNumber(num1 : Int,num2 : Int): Int{
return if(num1 > num2)
num1
else
num2
}
从函数的语法糖中我们可以将这段代码变得更加精简:
fun largerNumber(num1 : Int,num2 : Int) = if(num1 > num2) num1 else num2
Kotlin中的when语句有点类似于Java中的switch语句,但又远比switch语句强大的多。
Java的switch语句只能传入整型或短于整型的变量作为条件, JDK1.7之后增加了对字符串变量的支持,但是如果不是以上的几类变量,那么switch并不适合。
Kotlin中的when不仅解决了上述缺点,还增加了许多强大的新特性。
假设此时我们需要编写一个查询考试成绩的功能,输入一个学生的姓名,返回该学生考试的分数。
fun getScore(name : String) = if(name == "Tom") {
86
} else if (name == "Jim") {
77
} else if (name == "Jack") {
95
} else if (name == "Lily") {
100
} else {
0
}
这个getScore()
函数接收了一个学生姓名参数,然后通过if语句判断找到该学生的成绩并返回。但是if语句是否也太过冗余呢?
fun getScore(name : String) = when(name) {
"Tom" -> 86
"Jim" -> 77
"Jack" -> 95
"Lily" -> 100
else -> 0
}
when语句和if语句一样都可以有返回值
,因此我们同样可以使用单行代码的语法糖。
when语句允许传入任意一个类型的参数,然后可以在when的结构体中定义一系列条件,格式为:
匹配值 -> {执行逻辑}
。当执行逻辑只有一行代码时,{}
可以省略。
除了精确匹配外,when语句还允许进行类型匹配,此时我们定义一个checkNumber
函数:
fun checkNumber(num : Number) {
when(num){
is Int -> println("Number is Int")
is Double -> println("Number is Double")
else -> println("number not support")
}
}
上述代码中,is
关键字就是匹配的核心,它相当于Java中的instanceof
关键字。Number
是一个Kotlin内置的抽象类,像Int
、Double
、Long
等都是它的子类,因此此处就让checkNumber
函数接收一个Number
类型的参数,再进入判断。
fun main() {
val num = 12
checkNumber(num)
}
这里向checkNumber
函数传入了一个Int
型的参数,运行程序,结果如图:
when语句的基本用法就是这些。
when语句同样有不带参数的用法,虽然可能不太常用,但是有时候却能发挥很强的拓展性:
fun getScore(name : String) = when {
name == "Tom" -> 86
name == "Jim" -> 77
name == "Jack" -> 95
name == "Lily" -> 100
else -> 0
}
虽然这种无参数的when语句可能会比较冗余,但是有些场景必须使用它才能实现。
例如,所有名字以Tom开头的名字,分数都是86分,这种情况用有参数的when语句是无法实现的,但是不带参数的when语句却可以解决。
fun getScore(name : String) = when {
name.startsWith("Tom") -> 86
name == "Jim" -> 77
name == "Jack" -> 95
name == "Lily" -> 100
else -> 0
}
无论输入的是Tom
还是Tomxx
,输出都是86分
fun main() {
val name = "Tom and Jerry"
print(getScore(name))
}
while循环的用法与Java中的while循环没有任何区别,因此直接跳过。
Kotlin在for循环方面做出了较大幅度的改变,Java中最常用的for - i
循环在Kotlin中直接被舍弃了,而for - each
循环则被大幅度加强,成为了for - in
循环,因此我们只需要学习for - in
循环即可。
..
关键字我们可以用如下Kotlin代码来表示一个区间
val range = 0..10
..
关键字代表的是一个双端闭区间
。
fun main(){
val range = 0..10
for (i in range) println(i)
}
until
关键字在很多情况下,双端闭区间并没有单端闭区间好用,因为我们的数组下标从0开始,直到n - 1结束。例如arr[10]
的下标是0到9
,此时就可以用until
关键字创建一个左开右闭的区间
fun main(){
val range = 0 until 10
for (i in range) println(i)
}
step
关键字当我们用Java时,循环时常会有i += 2
的情况出现,但是Kotlin并没有for - i
语法,因此无法使用这项,所以Kotlin出现了step
关键字。
fun main(){
val range = 0 until 10
for (i in range step 2) println(i)
}
downTo
关键字前面的..
关键字和until
关键字都要求区间的左端点必须小于等于区间的右端点,即这两个关键字都是创建一个升序
的区间。如果要用降序的区间,就需要使用downTo
关键字:
fun main(){
val range = 10 downTo 0
for (i in range) println(i)
}