Kotlin语法梳理(一)

Kotlin语法梳理(一)_第1张图片

Kotlin语法梳理(二)

目录

Kotlin语法梳理(一)_第2张图片

声明变量

声明变量使用 varval关键字,如下:

var | val 变量名 [:类型] [= 初始值]

var n : Int = 0
var s : String = "变量的定义" // var声明的是变量,val声明的是常量

和 Java 的不同之处是,变量类型写在变量名后面了,和 go 语言类似。在Kotlin中每条语句的最后不用加分号。

数据类型

与Java基本类型相对应,Kotlin也有8中基本数据类型:

  • 整数类型:Byte、Short、Int和Long,Int是默认类型。
  • 浮点类型:Float和Double,Double是默认类型。
  • 字符类型:Char。
  • 布尔类型:Boolean。

Kotlin的8个基本数据类型没有对应的包装类Kotlin编译器会根据不同的场景将其编译成为Java中的基本类型数据还是包装类对象。例如,KotlinInt用来声明变量、常量、属性、函数参数类型和函数返回类型等情况时,被编译为Java的int类型;当作为集合泛型类似参数时,则被编译为Java的java.lang.Integer,这是因为Java集合中只能保存对象

数据类型之间的转换

Kotlin中要想实现这种赋值转换,需要使用转换函数显式转换。Kotlin中不能像Java中那样的自动类型转换,必须显示转换;Kotlin的6种数值类型(Byte、Short、Int、Long、Float和Double),以及Char类型都有如下7个转换函数: toByte(), toShort(): , toInt(),toLong(),toFloat(), toDouble(), toChar() 通过上述7个转换函数可以实现7种类型(Byte、Short、Int、Long、Float、Double和Char)之间的任意转换。

var n1 :Int = 10 //或者 var n1 = 10,整数默认为Int
var n2 :Double = n1.toDouble() //必须显示转换

非空安全

Kotlin默认是非空的,在非空类型后面加上问号“?”表示可空类型。

var str : String = null //错误的代码,默认非空
var str : String? = null //标识可空

可空类型在具体使用时会有一些限制: 不能直接调用可空类型对象的函数或属性。 不能把可空类型数据赋值给非空类型变量。 不能把可空类型数据传递给非空类型参数的函数。

var str : String? = null
........
str.length //错误代码,可空类型不能直接调用可空类型对象的函数或属性

为了“突破”这些限制,Kotlin提供了如下运算符: 安全调用运算符:?. Elvis运算符:?: 非空断言:!!

可空类型变量使用安全调用运算符?. 可以调用非空类型的函数或属性。安全调用运算符?. 会判断可空类型变量是否为空,如果是则不会调用函数或属性,直接返回空值;否则返回调用结果。

var str : String ? = null
var length = str!!.length //非空断言,一旦str为空,抛出空指针异常
var str : String? = null
var length =  str?.length //如果str不为空直接调用,如果为空直接返回null,而不会抛出空指针异常

如果为空时不想返回null,通过?:可以执行为空时的返回值
var length =  str?.length?:0 //str为空时返回0  A ?: B,如果A不为空值则结果为A,否则为B

常量

Kotlin声明常量是在标识符的前面加上valconst val关键字,它们的区别如下:

  • val声明的是运行期常量,常量是在运行时初始化的。
  • const val 声明的是编译期常量,常量是在编译时初始化,只能用于顶层常量声明或声明对象中的常量声明,而且只能是String或基本数据类型(整数、浮点等)。

给Java程序员的提示 编译期常量(const val)相当于Java中public final static所修饰的常量。而运行期常量(val)相当于Java中final所修饰的常量。

运算符

Kotlin==运算符equals函数等同于Java的equals函数。Kotlin中的===运算符等同于Java的==运算符。

定义方法

fun [方法名] ( [参数名] : [参数类型] ) : [返回类型]{
...
return [返回值]
}

fun add(m:Int, n:Int):Int {
  return m + n
}

//也可以写成表达式的方式:
fun add(m : Int, n : Int) : Int = m + n

流程控制语句

Kotlin流程控制语句的结果可以直接赋值给一个变量

//java传统写法
if (a > b) {
    max = a
} else {
    max = b
}

// kotlin写法
val max = if (a > b) a else b

when语句

when 取代了类 java中的 switch 操作符。其最简单的形式如下:

when (i) {
    1 -> {
       //操作。。。。
    }
    2 -> {
        //操作。。。。
    }
    else -> {
        //操作。。。。
    }
}

此外,还可以使用in或者!in表达式结果是否在一个范围或集合中;可以用is或者!is表达式结果是否是某一类型的对象

when (x) {
    in 1..10 -> print("x is in the range")
    in validNumbers -> print("x is valid") //validNumbers 为一个集合
    !in 10..20 -> print("x is outside the range")
    else -> print("none of the above")
}
when (view) {
    is TextView -> toast(view.text)
    is RecyclerView -> toast("Item count = ${view.adapter.itemCount}")
    is SearchView -> toast("Current query: ${view.query}")
    else -> toast("View type not supported")
}

when语句还可以省略表达式,此时分支条件表达式默认为Boolean型,在分支为true时会执行分支

when {
    a is String -> print("传入的值是String类型")
    a is Int -> print("传入的值是Int类型")
    a is Long -> print("传入的值是Long类型")
    a is ExampleUnitTest -> print("传入的值是ExampleUnitTest类型")
}

for循环

for (item in stringArrays){
        println(item)
 }

for语句遍历集合时,一般不需要循环变量,但是如果需要使用循环变量,可以使用集合indices属性

for (i in stringArrays.indices) {
     println(stringArrays[i]) //i为索引
 }

还可以指定一个范围

for (i in 0..10 step 1) { // step 1 指定步长(i每次加几)可以省略,默认为1
    println(stringArrays[i])
}

forEach 使用

stringArrays.forEach {  //stringArrays为一个集合
    println(it); 
}

还可以在遍历的时候获取索引

mlist.forEachIndexed { index, value ->   //index为索引,value为索引对应的值
    println("第${index}个值为:$value")
}

return,break和continue

Kotlin 和java一样,有三种结构化跳转表达式:
return :从包围它的函数或匿名函数返回
break : 终止循环
continue: 跳出本次循环,继续下一次循环

和Java不同的是,这些表达式都可作为更大表达式的一部分:

val s = person.name ?: return

breakcontinue语句都有两种方式:带有标签和不带标签

loop@ for (i in 1..100) {  //" loop@ "定义的标签   格式为:名字@
    for (j in 1..100) {
        if (……) break@loop // 终止loop标记的循环
        if (……) continue@loop // 跳出loop标记的循环,继续下一次loop标记的循环
    }
}

**return ** 也支持 @标签标签,只是标签定义的地方不同

mList.forEach lit@ {
    if (it == 0) return@lit // 标记从forEach{}返回
    print(it)
}

//用隐式标签(与接收lambda的函数同名)从lambda表达式中返回:
mList.forEach {
    if (it == 0) return@forEach // 隐式标签forEach,从forEach{}返回
    print(it)
}

需要注意的是:当return返回值时,表示的含义是不一样的

return@a 1 // 从@a标记的函数返回1,不是返回标记的表达式(@a 1)”。

不带标签的用法与Java中的一样。

总结

上述只是一些简单的语法,跟java中的用法差不多,只是功能更强大一些,使用起来确实很方便;重点是在类相关语法那块与Java中有很大的不同,内容也比较多。下一篇主要来梳理类相关的语法以及注意点。

你可能感兴趣的:(Kotlin语法梳理(一))