一、基本语法
1. 表达式的使用
//1、函数声明,可用表达式,自动推断返回类型之类的
fun sum(a:Int,b:Int):Int{
return a + b
}
//改为表达式,并自动推断返回类型
fun sum(a:Int,b:Int) = a+b
//2、结合条件判断的表达式
fun max(a:Int,b:Int):Int{
if(a>b){
return a
}else{
return b
}
}
//可简写为
fun max(a:Int,b:Int):Int{
return if(a>b) a else b
}
//进一步,表达式形式
fun max(a: Int, b: Int) = if (a > b) a else b
2. 可空值?
类型检测null
//可空类型声明,标准类型加上?,如Int对应可空的Int?
fun parseInt(str:String):Int?{
//因为str不一定就是数字的,所以返回可以为null,在调用处就需要处理
//return ...
}
//调用方判断非空
val x = parseInt("123")//返回类型为Int?
if(x!=null){
val c = x*2//如此才能正常使用
}
//空安全判断
var a:String?=null
a?.subString(5)?.length//因为a可空类型,所以使用?去操作,避免空指针,前面有一个null,后面都不会执行,而且不会抛出异常
a!!.subString(5).length//这里强判断!!非空,那么后面就认为不空,一旦a为null,就抛出异常了
//使用Elivs操作符,若a不空,则sa = a,空则赋值默认值
val sa = a?:return "default"//return 可以省略
val sssa = a?: throw Exception("null")
3. 类型检测is
、!is
//is 类型判读,会在is之后,就能使用它认定的类型,进行操作
val str:Any
if(str is String){
//在这里就认定为String类型了
println(str.length)
}
//或者
if(str !is String) return
println(str.length)//上面判断return后,这里也就认定为String了
//或者在同一个条件语句中,前面判断后,后面都可以认定类型
if(str is String &&str.length>0){
//......
}
4. for循环,使用in
、 或者..
、Range
//for循环
val array = (0..9).toList()//IntRange转化为list
for(i in array){
println(i)
}
for(i in "addgadsg"){
println(i)
}
for(i in 0..5){
//这里取值区间[0,5]
}
for(i in 0 until 5 step 1){
//这里取值区间[0,5)
}
//使用indices
for(i in array.indices){
println(array[i])
}
for(i in 9 downTo 0 step 2){
//递减,设置幅度的循环
}
5. When表达式
//类似于其他语言的switch case,但是更强大,结合表达式
fun picker(obj:Any) =
when(obj){
1,2,3->"Number"
"str"->"string"
is Long -> "oneLong"
!in 0..5 -> "no,no,no"
else -> "unknown"
}
//甚至必要时,可以不写表达式
when{
1 in 0..5 -> println()
2 !is String -> println()
}
6. 高阶函数及lambda
val fruits = lastOf("apple","banana","avocado","pear","peach")
//高级函数,lambda
fruits.filter{it.startWitch('a')}
.sortedBy{it}
.map{it.toUpperCase()}
.forEach{ println(it)}
7. isInitialized
lateinit var a:String
//在使用的时候,a未必就一定初始化了,可以两种方式处理
//1,将a声明为String?并=null赋值,那么用的时候,使用a?.去操作,
//2,使用`isInitialized`判断是否初始化了
if(a.isInitialized) //do something
8. typealias
类型别名
class PersonWithLongNameAndErrorSpell{}
//为了方便代码,可以声明类的别名
typealias Person = PersonWithLongNameAndErrorSpell
类的别名并不会创建新的类,只是一个外衣指针
9. infix
声明中缀函数
//中缀函数,作用于同类型的数据对象,而且函数声明在类之中
class DemoInt(value:Int){
var mInt = value
//中缀函数声明
infix fun sumInfix(sumTo:DemoInt){
return this.mInt+sumTo.mInt
}
}
//普通的sum函数是
fun sum(a:Int,b:Int) = a+b
//DemoInt使用中缀函数的求和
val a = DemoInt(2)
val b = DemoInt(3)
a sumInfix b//就会得到和一个求和,
10. operator
操作符函数重载
//类似中缀函数,在对应类中声明函数,
class DemoInt(value:Int){
var mInt = value
//操作符重载,这里是重载了 + 号
operator fun plus(demo:DemoInt){
println("$mInt , ${demo.mInt}")
}
}
//如此对于DemoInt对象就可以用+操作
val a = DemoInt(2)
val b = DemoInt(3)
a+b//这里就是调用了内部重载的plus函数