1.5 选择结构语句
- if 条件语句
当 if 条件满足时,即为 true 时,就走对应的代码块执行语句
fun main(args : Array<String>){ var max : Int = 0 var a : Int = 5 var b : Int = 6 if (a < b){ max = b }else{ max = a } print("max="+ max) //max=6 //上面的if else 可以简写成 三元运算符 var maxx = if (a > b) a else b print("maxx="+ maxx) }
kotlin 中的三元运算符表达式写法 if ( a > b) a else b
- when 条件语句
fun main(args : Array<String>){ var week : Int = 3 when(week){ 1 -> print("星期一") 2 -> print("星期二") 3 -> print("星期三") 4 -> print("星期四") 5 -> print("星期五") 6 -> print("星期六") 7 -> print("星期日") else -> { print("输入的数字不正确.....") } } //星期三 }
当 when 中表达式值和目标值匹配时,就执行 -> 后面的语句,类似 Java 中的 switch
fun main(args : Array<String>){ var month : Int = 9 when(month){ 12, 1, 2 -> print("冬季") 3, 4, 5 -> print("春季") 6, 7, 8 -> print("夏季") 9, 10, 11 -> print("秋季") else -> { print("没有该月份,请重新输入.....") } } //秋季 }
1.6 循环结构语句
- while 循环语句
fun main(args : Array<String>){ var n : Int = 4 while (n > 0){ println("n="+n) n-- } //n=4 //n=3 //n=2 //n=1 }
- do…while 循环语句
fun main(args : Array<String>){ var n : Int = 4 do { println("n="+n) n-- } while (n > 0) //n=4 //n=3 //n=2 //n=1 }
- for 循环语句
fun main(args : Array<String>){ //循环4次,且步长为1进行递增,0..3 表示[0,3]之间的数字 for (i in 0..3){ println("i => $i \t") } //i => 0 //i => 1 //i => 2 //i => 3 }
当 for 循环只有一条执行语句,可以省略 {}, 简写成
for (i in 0…3) println(“i => $i \t”)
- 循环嵌套
fun main(args : Array<String>){ //循环5次,且步长为1进行递增,0..5 表示[0,5]之间的数字 for (i in 0..5){ for(j in 0..i){ print("*") } print("\n") } //* //** //*** //**** //***** //****** }
- forEach 循环语句
1.普通的 forEach 语句
调用者.forEach(){
println(“it=${it}”)
}
调用者可以是数组或集合, it 表示数组中的元素
fun main(args : Array<String>){ //定义arr数组并初始化 var arr : IntArray = intArrayOf(1, 2, 3, 4) arr.forEach { print(it.toString() + "\t") } //1 2 3 4 }
2.带角标的 forEachIndexed 语句
调用者.forEachIndexed(){
index, it ->
println(“角标=i n d e x 元 素 = index元素=index元素={it}”)
}
index 表示数组角标或集合索引, it 表示数组角标或集合索引 对应的元素
fun main(args : Array<String>){ //定义arr数组并初始化 var arr : IntArray = intArrayOf(1, 2, 3, 4) arr.forEachIndexed { index, it -> println("角标=$index 元素=${it}") } //角标=0 元素=1 //角标=1 元素=2 //角标=2 元素=3 //角标=3 元素=4 }
- 跳转语句(continue、break)
1.break 语句
停止循环,跳出整个循环
注意: 当 break 出现在嵌套循环的内层循环中时,它只能跳出内存循环,如果想要跳出外层循环则需要对外层循环添加 loop@
fun main(args : Array<String>){ //循环9次,且步长为1的递增 loop@ for (i in 0..9){ //外层循环 for (j in 0..i){ //内层循环 if (i > 4){ //判断i是否大于4 break@loop //跳出外层循环 } print("*") //打印* } print("\n") //换行 } //* //** //*** //**** //***** }
2.continue 语句
终止当前这一次循环,继续下一次
fun main(args : Array<String>){ var sum : Int = 0 //定义一个变量sum,用于记录奇数的和 //循环100次,且步长为1的递增,1 until 101 表示 [1,101], 其中不包含数字101 for (i in 1 until 101){ if (i % 2 == 0){ //判断i是一个偶数时,不累加 continue //结束本次循环 } sum += i //实现sum和i的累加 } print("sum="+ sum) //打印奇数的和 //sum=2500 }
1.7 Kotlin 区间
- 正向区间
区间通常是指一类数据的集合。例如,由符合 0 <= a <= 1 的实数组成的一个集合便是一个区间。
在 Kotlin 中,区间通过 rangeTo(other : Int) 函数构成区间表达式,也可以用 “…” 操作符表示。
fun main(args : Array<String>){ for(i in 1.rangeTo(4)){ print(i.toString() + "\t") } print("\n") for (i in 1..4){ print(i.toString() + "\t") } //1 2 3 4 //1 2 3 4 }
注: Kotlin 中还有另外一个函数 until(to : Int), 该函数和 rangeTo() 非常相似,只不过前
者不包含结尾元素,并且该函数使用时可省略(),在 util 后面加上空格符,空格符后面加上范围值即可
fun main(args : Array<String>){ for(i in 1 until 4){ print(i.toString() + "\t") } // 1 2 3 }
- 逆向区间
上面的区间其实是按照一个正向顺序执行的区间,在 Kotlin 中,也可以通过 downTo(to : Int) 函
数实现逆向区间,该函数也可省略(), 在 downTo 后面加上空格符。
fun main(args : Array<String>){ for(i in 4 downTo 1){ print(i.toString() + "\t") } // 4 3 2 1 }
- 步长
上面介绍的区间默认使用的步长都是1,即每次递增或递减的差值为1,可以通过 step(step : Int)
函数来指定步长。同样可以省略(), 在 step 后面加空格符,再加上步长。
fun main(args : Array<String>){ for(i in 1..4 step 2){ print(i.toString() + "\t") } print("\n") for (i in 4 downTo 1 step 2){ print(i.toString() + "\t") } // 1 3 // 4 2 }
1.8 Kotlin 数组
- 数组定义
在 Kotlin 中,数组使用 Array 表示,其中可定义的类型有 数值类型、布尔类型、字符类型、字符串类型。
//第一种定义方式 var int_array : IntArray = intArrayOf(1, 2, 3) //第二中定义方式 var int_array1 : Array<Int> = arrayOf(1, 2, 3) var string_array : Array<String> = arrayOf("a", "b", "c")
- 数组常用操作
1.数组遍历
- for 循环遍历数组,依次访问数组中的每个元素
fun main(args : Array<String>){ var intArray : IntArray intArray = intArrayOf(1, 2, 3, 4) for (i in intArray){ println(i) } // 1 // 2 // 3 // 4 }
- for 循环遍历数组中元素及角标
fun main(args : Array<String>){ var intArray : Array<Int> intArray = arrayOf(1, 2, 3, 4) intArray[0] = 10 //将角标为0对应的元素设置为10 intArray.set(3, 16) //将角标为3对应的元素设置为16 intArray.forEachIndexed { index, i -> println("角标=$index 元素=$i") } //角标=0 元素=10 //角标=1 元素=2 //角标=2 元素=3 //角标=3 元素=16 }
2.数组最值
操作数组元素时,经常需要获取数组中的元素的最值。
fun main(args : Array<String>){ var arr : IntArray = intArrayOf(1, 2, 3, 4) var max = arr[0] for (i in arr){ if (i > max){ max = i } } println("max=" + max) //max=4 }
3.数组元素修改
例1中已经演示过了,通过 数组[角标] = 新值,或通过 set(角标, 新值) 函数修改
4.查找数组元素角标
fun main(args : Array<String>){ var newArray : Array<Int> = arrayOf(8, 4, 5, 4, 9) println("第1个元素4的角标="+newArray.indexOf(4)) var index = newArray.indexOfFirst { it == 4 } println("第1个元素4的角标="+index) println("最后1个元素4的角标="+newArray.lastIndexOf(4)) var indexL = newArray.indexOfLast { it == 4 } println("最后1个元素4的角标="+indexL) //第1个元素4的角标=1 //第1个元素4的角标=1 //最后1个元素4的角标=3 //最后1个元素4的角标=3 }
1.9 Kotlin 变量类型转换
- 类型检查
为避免变量在进行类型转换时,由于类型不一致而出现类型转换异常问题,可通过操作 is 或 !is 检测
对象是否是特定类的一个实例,有点类型 Java 中的 instance
fun main(args : Array<String>){ var a : Any = "hello" var result1 = a is String var result2 = a !is String println(result1) println(result2) //true //false }
智能类型转换
Kotlin 编译器是非常智能的,它能识别 is 和 !is 操作符,这样就能判断出当前对象是否属于后面的
数据类型。如果当前对象属于 is 后面的数据类型,则在使用该对象时会自动进行智能类型转换。
fun main(args : Array<String>){ var a : Any = "hello" if (a is String){ println("a is String") println("字符串长度:" + a.length)//操作时自动转换为String类型 }else if (a !is Int){ println("a !is Int") }else{ println("I don't know") } //a is String //字符串长度:5 }
- 强制类型转换
使用到的操作符为
as 进行强制类型转换,转换失败则抛出异常
as? 进行强制类型转换,转换失败,不抛出异常,返回 null
fun main(args : Array<String>){ var a = 1 var b : String = a as String print(b.length) //上面的情况会抛出 异常 var c : String? = a as? String print(c?.length) }
2.0 Kotlin 空安全
- 可空类型变量( ? )
Kotlin 中声明可空类型变量和非空类型变量如下
var name : String //声明可空变量
var age : Int? //声明非空变量
在使用可空变量时,如果不知道变量的初始值,则需要将其赋值为 null, 否则会报 " Variable age must be initalizd" 异常。
fun main(args : Array<String>){ var name : String = "Mike" var telephone : String? = null if (telephone != null){ print(telephone.length) }else{ telephone = "18386868989" print("telephone = " + telephone) } //telephone = 18386868989 }
- 安全调用符( ?. )
为了替代上面的复杂可空变量判断 if…else 逻辑, Kotlin 提供了一个安全调用符 ?.
语法格式为, “变量?.成员”, 只有当变量不为 null 时,才调用变量的成员方法或属性
fun main(args : Array<String>){ var name : String = "Mike" var telephone : String? = null var result = telephone?.length print(result) //null }
Evlis 操作符( ?: )
在使用安全调用符调用可空变量中的成员方法或属性时,如果当前变量为空,则会返回一个 null 值,
但有时即使当前变量为 null,也不想返回一个 null 而是指定的一个默认值。那么该如何处理呢?
Kotlin 为此提供了一个 Evlis 操作符( ?: ), 语法格式为 “表达式?:表达式”。如果左侧表达式
非空,则返回左侧表达式的值,若为空,则返回右侧表达式的值。
fun main(args : Array<String>){ var name : String = "Mike" var telephone : String? = null var result = telephone?.length ?: "18386868989" print(result) //18386868989 }
- 非空断言( !!. )
在 Kotlin 中还可以通过非空断言( !!. )来调用可空类型变量的成员方法或属性。 语法格式为
“变量!!:成员”, 非空断言会将任何变量(可空类型变量或非空类型变量)转换为非空类型的变量,若为
空则抛出异常。
fun main(args : Array<String>){ var name : String = "Mike" var telephone : String? = null var result = telephone!!.length print(result) //Exception in thread "main" kotlin.KotlinNullPointerException // at cn.test.kotlin.KtTestKt.main(KtTest.kt:8) }
程序抛出了空指针异常,如果变量 telephone 赋值不为空,则程序正常运行。
空安全调用符 和 非空断言都可以调用可空变量的方法,当相比而言,空安全调用符更安全,不会抛出异常,推荐使用空安全调用符。