为String添加firstChar函数
fun String.firstChar():String{
if(this.length() == 0){
return "";
}
return this[0].toString()
}
在代码中直接调用该函数
"abc".firstChar()
引入不可空类型与可空类型
编译期通过类型是否匹配来检查空指针异常
提供Elvis操作符、安全调用符等极简的语法格式
不可空类型 var a = “abc”,则a = null 会报错,因为a声明了不可空类型String
可空类型 var b:String? = “abc” 调用b.length 还是会报错,需要使用安全调用符(?.)或断言调用符(!!)
—>b?.length or b!!.length
Kotlin中函数是第一等类型,一个函数可以作为另一个函数的返回值,称为一等函数支持
在声明变量时未显式指定其类型,编译器其中会自动推断其类型
Kotlin中,所有的变量都是引用类型,命名同Java遵循驼峰式命名法
val:只读,仅能一次赋值(可以带来可预测的行为,线程安全)
var:可写,可以被多次赋值
val a:Int = 1 //用val声明一个不可变的常量a
//编译器能够自动推断类型,所以可以省去类型代码
val a = 1
a++ -> error: var cannot be reassigned //a不可以重新赋值
var b = 1 //用var声明一个可变的变量b
b = b + 1 //b可以被多次赋值
一些关键字不能被用作变量名
分支语句 if、when
循环语句 while、for
跳转语句 return、break、continue、throw
fun main(args : Array<String>){
println(max1(1,2))
}
fun max1(a : Int, b: Int): Int{
//表达式返回值
val max = if(a>b) a else b //表达式返回值,相当于Java三元表达式
return max
}
fun max2(a : Int, b : Int): Int{
//代码块返回值
val max = if(a > b){
println("最大数是" + a)
a //if作为代码块时,最后一行为其返回值
}else{
println("最大数是" + b)
b
}
return max
}
ps. if后的括号不能省略,括号内表达式的值必须式布尔型
e.g 用if…else语句判断年份是否是闰年
fun ifLeapYear(year : Int) : Boolean{
var isLeapYear : Boolean //声明一个局部变量
if(year % 4 == 0 && year % 100 != 0 ) || (year % 400 == 0){
//判断是否是闰年
isLeapYear = true
}else{
isLeapYear = false
}
return isLeapYear
}
fun main(args : Array>String){
println(isLeapYear(2017)) //不是闰年
println(isLeapYear(2018)) //是闰年
}
类似于switch…case…,对所有分支进行检查直到有一个条件被满足。
fun caseWhen(obj : Any?){
val x = "123"
when(x){
0,1,2,3,4,5,6,7,8,9 -> println("${obj} ===> 这是一个0-9的数字")
"hello" -> println("${obj} ===> 这是一个字符串hello") //is 类型判断
is Char -> println("${obj} ===> 这是一个Char类型数据")
parseInt(x) -> println("可以用任意表达式(而不只是常量)作为分支条件")
in 1...10 -> println()
else -> println("else类似于Java中switch...case...语句中的default")
}
}
fun main(args : Array<String>){
caseWhen(7)
caseWhen("hello")
caseWhen('a')
caseWhen(null)
}
也可以检测在(in)或者不在(!in)一个区间或集合中
val x = 1
val validNumbers = arrayOf(1,2,3)
when(x){
in 1..10 -> println("x is in the range")
in validNumbers -> println("x is valid")
!10..20 -> println("x is outside the range")
else -> println("none of the above")
}
用when语句写一个阶乘函数
fun fact(n : Int): Int{
val result = 1
when(n){
0,1 -> result = 1
else -> result = n * fact(n-1)
}
return result
}
fact(10) //3628800
for循环可以对任何提供迭代器(iterator)的对象进行遍历
//for in 循环
for(item in collection){
println(item);
}
遍历数组或list时
for(i in array.indices){ //array.indices持有数组的下标列表
println(array[i]);
}
for((index, value) in array.withIndex()){
println("数组位置$index的值是$value");
}
范围(Ranges)表达式也可用于for循环中
for(i in 1..10){ //1..10等价于1.rangeTo(10)
println(i)
}
//简写如下
(1..10).foreach(){ println(it) }
e.g 输出1-n阶乘的和(1! + 2! + … +n!)
public void sunFact(n : Int){
var sum = 0
for(i in 1..n){
sum += fact(i)
}
}
while与do…while循环语句的使用方式与C、Java语言基本一致
fun main(args : Array<String>){
var x = 10
while(x > 0){
x-
println(x)
}
var y = 0
do{
y = y + 1
println(y)
}while(y > 10)
}
问题场景1:打印数字1~10,只要遇到偶数就结束打印
for(i in 1..10){
println(i)
if(i % 2 == 0){
break
}
}
问题场景2:打印1~10中的奇数
//正常
for(i in 1..10){
if(i % 2 != 0){
println(i)
}
}
//使用continue
for(j in 1..10){
if(j % 2 == 0){
continue
}
println(j)
}
在Kotlin中,出了表达式的值,有返回值的函数都要求显式使用return语句返回其值
fun sum(a : Int, b : Int) : Int{
return a + b //这里的return不能省略
}
fun max(a : Int, b : Int):Int{
if(a > b){
return a //这里的return不能省略
}else{
return b //这里的return不能省略
}
}
Kotlin中可以直接用“=”来返回一个函数的值,这样的函数称为函数字面量,示例如下:
fun sum(a : Int, b : Int) = a + b
fun max(a : Int, b : Int) = if(a > b) a else b
val sum1 = fun(a : Int, b = Int) = a + b //使用fun关键字声明了一个匿名函数,并且直接使用表达式来实现函数
val sum2 = fun(a : Int, b = Int) = {a + b} //后面函数体语句中有大括号{}则返回的是一个Lambda表达式
val sumf(kotlin.Int, kotlin.Int) -> () -> kotlin.Int //sumf是一个高阶函数类型,{a+b}的类型是从(kotlin.Int, kotlin.Int)到()->kotlin.Int的映射函数
>>> sumf(1,1) //调用sumf(1,1),返回的是一个函数
() -> kotlin.Int //sumf(1,1)的返回值是一个函数() -> kotlin.Int,而不是具体的数值
sumf(1,1).invoke() //使用invoke函数实现真正调用函数
sumf(1,1)() //使用括号()调用函数,与invoke()等价
在Kotlin中,()操作符对应的是类的重载函数,如invoke().两者是等价的