kotlin学习笔记01
1.1变量和函数
1.1.1变量
在kotlin中定义一个变量,只允许在变量前声明两种关键字: val和 varval
(value)用来声明一个不可变的变量,这种变量在初试赋值之后就不在能重新赋值var
(variable)用来声明一个可变的变量,这种变量在初试赋值之后仍然可以再被重新赋值
那么我们应该什么时候使用val,什么时候使用var呢?
永远优先使用val来声明一个变量,而当val没有办法满足你的需求时再使用var。这样设计出来的程序会更加健壮,也更加符合高质量的编码规范。
1.1.2 函数
自定义函数
语法规则:
fun methodName (param1: Int, param2:Int):Int {
return 0
}
1.参数的声明格式是“参数名: 参数类型”
2.参数括号后面的那部分是可选的,用于声明该函数会返回什么类型的数据,上述示例就表示该函数会返回一个Int
类型的数据。如果你的函数不需要返回任何数据,这部分可以直接不写。
调用函数示例:
package com.example.myapplication02
import kotlin.math.max
fun largerNumber(num1: Int, num2: Int):Int{
return max(num1,num2)
}
fun main(){
val a:Int =10
val b:Int =20
val v=largerNumber(a,b)
print("v="+v)
}
主函数调用了一个封装好的
largerNumber
函数
1.1.3 语法糖
当一个函数中只有一行代码时,Kotlin
允许我们不必编写函数体,可以直接将唯一的一行代码写在函数定义的尾部,中间用等号连接即可。比如我们刚才编写的largerNumber()
函数就只有一行代码,于是可以将代码简化成如下形式:
fun largerNumber(num1: Int, num2: Int):Int = max(num1,num2)
使用这种语法,return
关键字也可以省略了,等号足以表达返回值的意思。另外,还记得Kotlin
出色的类型推导机制吗?在这里它也可以发挥重要的作用。由于max()
函数返回的是一个Int
值,而我们在largerNumber()
函数的尾部又使用等号连接了max()
函数,因此Kotlin
可以推导出largerNumber()
函数返回的必然也是一个Int
值,这样就不用再显式地声明返回值类型了,代码可以进一步简化成如下形式:
fun largerNumber(num1: Int, num2: Int) = max(num1,num2)
1.2 程序的逻辑控制
程序的执行语句主要分为3种:顺序语句、条件语句和循环语句。
1.2.1 if条件语句
Kotlin
中的条件语句主要有两种实现方式:if
和when
。
还是以上一节中的largerNumber()函数为例,之前我们借助了Kotlin内置的max()函数来实
现返回两个参数中的较大值,但其实这是没有必要的,因为使用if判断同样可以轻松地实现这个功能。将largerNumber()函数的实现改成如下写法:
fun largerNumber(num1: Int, num2: Int):Int{
var value = 0
if (num1 > num2) {
value = num1
}else{
value = num2
}
return value
}
这里使用了var关键字来声明value这个变量,这是因为初始化的时候我们先将
value赋值为0,然后再将它赋值为两个参数中更大的那个数,这就涉及了重新赋值,因此必须用var关键字才行。
Kotlin
中的if语句相比于Java
有一个额外的功能,它是可以有返回值的,返回值就是if
语句每一个条件中最后一行代码的返回值。因此,上述代码就可以简化成如下形式:
fun largerNumber(num1: Int, num2: Int):Int{
val value = if (num1 > num2) {
num1
}else{
num2
}
return value
}
注意这里的代码变化,if语句使用每个条件的最后一行代码作为返回值,并将返回值赋值给了
value
变量。由于现在没有重新赋值的情况了,因此可以使用val关键字
来声明value
变量,最终将value
变量返回。
仔细观察上述代码,你会发现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
1.2.2 when条件语句
编写一个查询考试成绩的功能,输入一个学生的姓名,返回该学生考试的分数。我
们先用上一小节学习的if语句来实现这个功能
fun gerScore(name:String) = if (name == "Tom") {
86
}else if (name == "Jim"){
77
}else if (name == "Jack"){
95
}else if (name == "Lily"){
100
}else {
0
}
虽然上述代码确实可以实现我们想要的功能,但是写了这么多的if
和else
,你有没有觉得代码很冗余?没错,当你的判断条件非常多的时候,就是应该考虑使用when
语句的时候,现在我们将代码改成如下写法:
fun getScore(name: String) = when (name) {
"Tom" -> 86
"Jim" -> 77
"Jack" -> 95
"Lily" -> 100
else -> 0
}
when语句允许传入一个任意类型的参数,然后可以在when的结构体中定义一系列的条件,格式是:
匹配值 -> {执行逻辑}
当你的执行逻辑只有一行代码时,{ }可以省略。
除了精确匹配之外,when语句还允许进行类型匹配
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关键字。由于checkNumber()
函数接收一个Number
类型的参数,这是Kotlin
内置的一个抽象类,像Int
、Long
、Float
、Double
等与数字相关的类都是它的子类,所以这里就可以使用类型匹配来判断传入的参数到底属于什么类型,如果是Int
型或Double
型,就将该类型打印出来,否则就打印不支持该参数的类型。
when语句的基本用法就是这些,但其实when语句还有一种不带参数的用法,虽然这种用法可能不太常用,但有的时候却能发挥很强的扩展性。
fun getScore(name: String) = when {
name == "Tom" -> 86
name == "Jim" -> 77
name == "Jack" -> 95
name == "Lily" -> 100
else -> 0
}
可以看到,这种用法是将判断的表达式完整地写在when的结构体当中。注意,Kotlin中判断字符串或对象是否相等可以直接使用==关键字,而不用像Java那样调用equals()方法。可能你会觉得这种无参数的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
}
1.2.3 循环语句
在开始学习for-in循环之前,还得先向你普及一个区间的概念,因为这也是Java中没有的东
西。我们可以使用如下Kotlin代码来表示一个区间:
val range = 0..10
上述代码表示创建了一个0到10的区间,并且两端都是闭区间,这意味着0到10这两个端点都是包含在区间中的,用数学的方式表达出来就是[0, 10]。
其中,…是创建两端闭区间的关键字,在…的两边指定区间的左右端点就可以创建一个区间
了。有了区间之后,我们就可以通过for-in循环来遍历这个区间,比如在main()函数中编写如下代码:
fun main(){
for (i in 0..10){
println(i)
}
}
这就是for-in循环最简单的用法了,我们遍历了区间中的每一个元素,并将它打印出来。现在运行一下程序
但是在很多情况下,双端闭区间却不如单端闭区间好用。为什么这么说呢?相信你一定知道数组的下标都是从0开始的,一个长度为10的数组,它的下标区间范围是0到9,因此左闭右开的区间在程序设计当中更加常用。Kotlin中可以使用until关键字来创建一个左闭右开的区间,如下所示:
val range = 0 until 10
上述代码表示创建了一个0到10的左闭右开区间,它的数学表达方式是[0, 10)。修改main()函数中的代码,使用until替代…关键字,你就会发现最后一行10不会再打印出来了。
默认情况下,for-in循环每次执行循环时会在区间范围内递增1,相当于Java for-i循环中
i++的效果,而如果你想跳过其中的一些元素,可以使用step关键字:
fun main() {
for (i in 0 until 10 step 2) {
println(i)
}
}
上述代码表示在遍历[0, 10)这个区间的时候,每次执行循环都会在区间范围内递增2,相当于
for-i循环中i = i + 2的效果。
可以看到,现在区间中所有奇数的元素都被跳过了。结合step关键字,我们就能够实现一些更加复杂的循环逻辑。
不过,前面我们所学习的…和until关键字都要求区间的左端必须小于等于区间的右端,也就是这两种关键字创建的都是一个升序的区间。如果你想创建一个降序的区间,可以使用downTo
关键字,用法如下:
fun main() {
for (i in 10 downTo 1) {
println(i)
}
}
另外,降序区间也是可以结合step关键字跳过区间中的一些元素的,这里我就不进行演示了,
你可以自己动手试一试。