kotlin语言的基础语法

Kotlin是一个用于现代多平台应用的静态编程语言,于2011年7月由  JetBrains 开发,这是一个基于JVM上运行的新语言;kotlin 语言是对 Java 语言的优化和封装,语法上有很多相似的地方,它们之间可以相互调用;kotlin 语言可以运用到 Web 前端开发、Web 后端开发、Android 移动端开发、server 脚本开发和桌面游戏开发这5类使用场景;所以学习 kotlin 语言是很有必要的,下面对它的语法进行探索。

**1、kotlin 语言的变量和输出
**

**1、1 变量
**

在程序运行过程中,随时可能会产生一些临时数据,应用程序将这些数据保存到一些内存单元,这些内存单元叫变量;变量包括变量名、 变量类型 和变量值;它的作用是用来存储一个数据,给这个数据起个名字方便开发人员使用该变量,它类似于容器;其中 var 声明的变量可读可写,val 声明的变量只可读。

常见的变量类型有8种

Byte   存储值范围 整数 -128~127
Short   存储值范围 整数 -32768~32767
Int   存储值范围 整数 -2147483648~2147483647
Long 存储值范围 整数 -9223372036854775807~9223372036854775807
Float   存储值范围 小数,小数点可以精确到6位
Double   存储值范围 小数,小数点可以精确到15-16位
String   存储值范围 字符串,用""双引号引起来的字符串都可以存
Boolean 存储值范围 布尔值,有2个,为 true 和 false

下面用代码对8中变量类型显式声明,举个例子:

ps:在 AndroidStudio 上写的代码

 var b:Byte = 123
 var s:Short = 32766
 var i:Int = 2
 var l:Long = 46L
 var f:Float = 47F
 var d:Double = 90.478326548359783
 var s2:String = "你好"
 var b2:Boolean = false

以上有些类型编译器容易自动推断,可隐式声明

 /**
 * 编译器推断为 Int型
 */
 var i2 = 2
 /**
 * 编译器推断为 Long 型
 */
 var l2 = 46L
 /**
 * 编译器推断为 Float 型
 */
 var f2 = 47F
 /**
 * 编译器推断为 Double 型
 */
 var d2 = 90.478326548359783
 /**
 * 编译器推断为 String 型
 */
 var s4 = "你好"
 /**
 * 编译器推断为 Boolean 型
 */
 var b3 = false

**1、2 输出
**

kotlin 的输出其实就是在控制台上输出一些内容,也就是打印,下面列举代码举例:

 /**
 * 在控制台上输出 你好,不换行
 */
 print("你好")
 /**
 * 在控制台上输出 你好,换行
 */
 println("你好")

**2、函数和函数式表达式
**

2、1 函数

函数是计算机执行命令的单元,描述的是行为,一般指的是对象所有可以被执行的行为或者动作;也可以理解为计算机里的函数是程序执行的小片段,这些小片段可以有机的组合在一起完成业务功能;它可以有返回值或者无返回值,可以有参数或者没有参数,用 fun 关键字声明;下面举一个例子:

 /**
 * 这是一个无参数无返回值的函数
 */
 fun function1() {
 println("这是一个无参数无返回值的函数")
 }
 /**
 * 这是一个有2个参数无返回值的函数;
 * 2个参数分别为String和Int类型
 */
 fun function2(s: String,i: Int) {
 println("这是一个有2个参数无返回值的函数")
 }
 /**
 * 这是一个无参数有返回值的函数;
 * 返回值类型为Int型
 */
 fun function3():Int{
 println("这是一个无参数有返回值的函数")
 return 1
 }
 /**
 * 这是一个有2个参数有返回值的函数;
 * 2个参数分别为String和Int类型;
 * 返回值为Int型
 */
 fun function4(s: String,i: Int):Int{
 println("这是一个有2个参数有返回值的函数")
 return 1
 }

2、1 函数式表达式

函数式表达式是一个代码量很少的函数的一种简化,类似 Java 中的 Lambda 表达式,也就是函数中只有一条语句且是返回值语句时,可以省略 return 关键字写成函数式表达式;下面列举一下函数可以写成函数式表达式的例子。

(1)有 fun 关键字的函数式表达式。

 /**
 * 定义有2个参数返回值为1的函数 function(x:Int,y:Int)
 */
 fun function(x:Int,y:Int):Int = 1

(2)无 fun 关键字的函数式表达式。

 /**
 * 这里可以理解成 定义函数名为 i,
 * 2个 Int 类型的参数 x 和 y,
 * 返回值为 Int 类型且返回值为 x*y 的函数
 */
 var i = {x:Int,y:Int -> x*y}
 var result = i(3,5)
 println(result)
 /**
 * 这里和 定义 i 函数也是一样的理解
 */
 var j:(Int,Int)->Int = {x,y ->x*y}
 var result2 = j(3,5)
 println(result2)

**3、字符串
**

3、1 字符串模板

字符串字面值可以包含模板表达式,即一些小段代码,会求值并把结果合并到字符串中;模板表达式以美元符 $ 开头,或者用花括号 ${}括起来的任意表达式;下面举个例子:

 var i:Int = 4
 var s:String = "公园"
 /**
 * i 求值为4并把4合并到字符串中
 */
 var s2:String = "今天我赚了${i}块钱"
 /**
 * s 求出为String类型值“公园”并把“公园”合并到字符串中
 */
 var s3:String = "如果明天不下雨,我们就去${s}玩"

**3、2 字符串的比较
**

这里说的字符串比较,是对比2个字符串的内容是否相等,而不是对比2个字符串是不是同一个对象,它的写法有3种,下面举个例子:

 var s4:String = "hello World"
 var s5:String = "hello world"
 /**
 * b 为 false
 */
 var b:Boolean = s4 == s5
 /**
 * b2 为false
 */
 var b2:Boolean = s4.equals(s5)
 /**
 * b3 为true,参数为true,表示不用区分字母的大小写
 */
 var b3:Boolean = s4.equals(s5,true)

**4、kotlin 的空值
**

kotlin 中的 null,它也是值,表示没有数据,没有东西;下面用 String 类型的变量举个例子:

 /**
 * 在类型后面加个? ,表示允许该类型变量为null
 */
 var s:String? = null
 var s2:String = "你好"
 /**
 * 这里 s3的值为 你好null
 */
 var  s3:String = s2 + s

5、when 表达式

在 Java 中,我们更多习惯用的是 switch/case 的模式,但是 switch/case 支持的类型非常少,用起来也有一些局限性;在 kotlin中,引入了 when 表达式,它能完全取代 switch/case,并且还有很多新的特性;when 表达式它是在给定条件基础上,满足什么条件就执行什么条件;下面对于不同情况下的 when  表达式举例子。

(1)when 表达式的一般用法

 var num:Int = 3
 when(num) {
 /**
 * 这里如果满足3,就执行3的语句,执行完之后就跳出循环,相等于
 * Java中的 case 3: break
 */
 3 -> println("当前数字为" + num)
 2 -> println("当前数字为" + num)
 1 -> println("当前数字为" + num)
 /**
 * 这里面的else等同于Java的switch/case中的default
 */
 else -> println("当前数字不为1 、2、3")
 }

(2)when 表达式还可以写成自变量自动转型类型

 var appCompatActivity: AppCompatActivity = MainActivity()
 when(appCompatActivity) {
 is MainActivity -> println("当前对象是MainActivity类型的")
 is Test -> println("当前对象是Tets类型的")
 else -> println("当前对象是其他类型的")
 }

(3)when 表达式还可以写成没有自变量的类型

 var s2:String = "你好"
 var i2:Int = 3
 when {
 s2 == "哈哈" -> println("s2 的内容为 哈哈")
 i2 == 3 -> println("i2 的值为 3")
 else -> println("其他输出")
 }

(4)when 表达式还可以有返回值且返回值不允许出现 return 关键字

 var num2:Int = 3
 /**
 * 1、when 表达式中的每一条执行语句的返回值类型必须一致,即 num2 和 0 是Int类型;
 * 2、接收返回值的变量类型必须与when 中执行语句返回值的类型一致,即num2 和 result类型一致
 */
 var result:Int = when(num2) {
 3 -> {
 println("当前的返回值为3")
 num2
 }
 else -> {
 println("当前的返回值为0")
 0
 }
 }

6、Range 和 for 循环

6、1 Range

Range 是 Kotlin 相对 Java 新增的一种表达式,它表示的是值的范围,类似于数学中的区间,区间里面的数一定是 Int 类型的。它的写法有4种:

(1) 数值1 .. 数值2,表示数值1到数值2的范围(包括数值1和数值2在里面);

(2) A1 unti A2,表示 A1 到 A2-1 的范围(包括 A1 但不包含 A2 在里面);

(3) A2 downTo A1,表示 A1 .. A2 的倒序(A2 > A1);

(4)A1 .. A2 step N,表示从A1开始取数,每隔 N 个数就取数,直到这个数不在 A1 和 A2 的范围内;

下面对它的语法进行举例:

 /**
 * 区间[1,10),不包含10在里面
 */
 var ia:IntRange = 1 until 10
 /**
 * 区间[1,10],包含1 和 10
 */
 var ia2:IntRange = 1 .. 10
 /**
 * 倒叙区间[10,1],包含10 和 1
 */
 val intRangeReverse = 10 downTo 1
 /**
 * 区间步长取数,从区间[1,10]取数,从1开始,每隔 3个数就取出一个,最终这个数不在
 * 区间内就算取完最终区间里存放的数为 1,4,7,10
 */
 var ia3 = 1 .. 10 step 3
 /**
 * 将 [1,10] 这个区间的数进行倒序,即[10,1]
 */
 var ia4 = ia2.reversed()
 /**
 * 获取区间[1,10]中的数量
 */
 var num:Int = ia2.count();

6、2 for 循环

for 循环的作用是遍历一个集合的元素,使其一个个的取出来使用,for 循环的括号里用关键字 in。

下面进行举例子:

 /**
 * 定义一个Int类型的数组
 */
 var ia:IntArray = intArrayOf(1,2,3,4,5)
 /**
 * 用for循环遍历Int类型的数组
 */
 for (i in ia) {
 println("i = " + i)
 }

7、List 和 Map

7、1 List

List 就是一个存储数据的列表,类似 Java中的List;构造 List 的函数如下所示:

(1)listOf(),表示构造一个空的 List;

(2)listOf(A),表示构造有一个数据的 List;

(3)listOf(A,B,C,...)表示构造多个数据的 List

下面用代码举个例子:

 /**
 * 构造一个没有数据的List
 */
 var list: List = listOf()
 /**
 * 构造一个只有一个数据的List
 */
 var list2: List = listOf("A")
 /**
 * 构造多个数据的List
 */
 var list3: List = listOf("A", "B", "C")

7、2 Map

Map 类似一个词典,词有索引,索引对应具体的内容,和 Java 中的 Map 类似构造 Map 的方法如下所示:

(1)mapOf(): 该函数返回不可变的 Map 集合
(2)mutableMapOf():  该函数返回可变的 MutableMap 集合
(3)hashMapOf():  该函数返回可变的 HashMap 集合
(4)linkedMapOf(): 该函数返回可变的 LinkedHashMap 集合
(5)sortedMapOf():  该函数返回可变的 TreeMap 集合
(6)TreeMap():该函数返回可变的 TreeMap 集合

下面用代码对构造 Map 举个例子:

 val map = mapOf("Android" to 56, "Kotlin" to 78, "C" to 74)
 println("mapOf() 的实际类型是:${map.javaClass}")
 val mutableMap = mutableMapOf("Android" to 56, "Kotlin" to 78, "C" to 74)
 println("mutableMapOf() 的实际类型是:${mutableMap.javaClass}")
 val hashMap = hashMapOf("Android" to 56, "Kotlin" to 78, "C" to 74)
 println("hashMapOf() 的实际类型是:${hashMap.javaClass}")
 val linkedMap = linkedMapOf("Android" to 56, "Kotlin" to 78, "C" to 74)
 println("linkedMapOf() 的实际类型是:${linkedMap.javaClass}")
 val treeMap = sortedMapOf("Android" to 56, "Kotlin" to 78, "C" to 74)
 println("sortedMapOf() 的实际类型是:${treeMap.javaClass}")
 var treeMap2 = TreeMap()
 treeMap2["Android"] = 56
 treeMap2["Kotlin"] = 78
 treeMap2["C"] = 74
 println("TreeMap() 的实际类型是:${treeMap2.javaClass}")

Map 的数据取出是用 for 循环一个个的遍历,它的写法如下所示:

(1)for (entry in map.entries) {  },for-in 遍历,遍历的是 Entry;

(2)for (key in map.keys) { },遍历 key,再通过 key 获取 value;

(3)for ((key, value) in map) { },for-in 遍历,key 和 value 同时遍历;

(4)map.forEach {  },forEach Lambda 表达式遍历;

下面用代码举个例子:

 /**
 * for-in 遍历,遍历的是 Entry
 */
 for (en in map.entries) {
 println("${en.key}: ${en.value}")
 }
 /**
 * 遍历 key,再通过 key 获取 value
 */
 for (key in map.keys) {
 println("$key: ${map[key]}")
 }
 /**
 * for-in 遍历,key 和 value 同时遍历
 */
 for ((key, value) in map) {
 println("$key: $value")
 }
 /**
 * forEach Lambda 表达式遍历
 */
 map.forEach {
 println("${it.key}: ${it.value}")
 }

8、字符串和数字之间的转换

8、1 字符串转换成数字

字符串转换成数字成功的前提是字符串里面的内容必须是数值,不能有其他符号,它的转换方式为:字符串对象.toInt(),下面举个例子:

 var s:String = "123"
 /**
 * 这里可以转换成为数字,因为s的内容都是数值
 */
 var num:Int = s.toInt()
 
 var s2:String = "12s"
 /**
 * 会报错;
 * 这里不可以转换成为数字,因为s2的内容不都是数值,含有s字符
 */
 var num2:Int = s2.toInt()

8、2 数字转换成字符串

数字转换成字符串没有条件限制,它的转换方式为:Int类型对象.toString(),下面举个例子:

 var num3:Int = 4
 var s3:String = num3.toString()
 println("s3 = " + s3)

9、异常

在 kotlin 程序中,错误可能产生于程序员没有预料到的各种情况,或者超出程序员可控范围的环境,例如试图打开一个不存在的文件,程序中就会运行出错;为了防止出现这种情况,我们必须要引用 kotlin 语言中的异常类;Kotlin 中所有异常类都是 Throwable 类的子孙类。 每个异常都有消息、堆栈回溯信息和可选的原因。

kotlin 中的捕获异常是由 try{}catch(e: Exception){}finally{} 语句组成,其中 catch 和 finally 至少要有一个存在,finally 不是必须的,可写可不写,不管程序是否捕获到异常,finally 里的代码块都会被执行,catch 代码块是处理异常的;下面进行代码举例:

 var s: String? = null
 try {
 /**
 * 这里的s是null值,会产生空指针异常
 */
 var b:Boolean = s.equals("123")
 } catch (e: Exception) {
 println("执行了catch代码块,因为s为null值")
 }finally {
 println("不管s是不是null值都会执行了finally代码块")
 }

本篇文章写到这里就结束了,由于技术水平有限,文章中难免会有错误,欢迎大家批评指正,另外附上demo地址:https://github.com/Yubao1/Kot...

你可能感兴趣的:(kotlin语言的基础语法)