Kotlin初探之语法简介分析
2017-08-03 17:35
302 查看
前言
部门经理让我在技术分享会上分享Kotlin的语法,因为Kotlin已经被Google定为一级开发语言了,正好之前也有学习Kotlin的计划于是花2天时间熟悉了下Kotlin的语法以及特性。语法
关于语法的介绍比较多,这里就贴一些典型的例子变量的声明
var a : Int?=null //?表示该变量可为null var b : Int = 2 // 不加?表示该变量不为null var c = "Hello World" //类型自推导
在Kotlin中声明变量是用标识符var ,常量用val
格式是
var 变量名 :类型?= .... //?表示该变量可为null,不加?表示该变量不为null
类型转换
var e : Long= b.toLong() //通过toLong(),toByte()等方法进行类型转换 var f : Int= "1".toInt() //将字符串"1"变为一个Int
字符串拼接
var name:String?="Bryant" var anotherName:String?= "Hello $name"
函数的定义
fun 关键字声明 具体形式 fun 函数名(变量名1 : 类型,变量名2 : 类型……):返回值类型
fun sum(a:Int,b:Int):Int = a+b //当函数返回单个表达式时,可以省略花括号并且在 = 符号之后指定代码体即可写成单表达式函数
//表达式有多个使用大括号,when的作用类似于Java中的Switch fun typeCheck(obj:Any):Int?{ when(obj){ !is Int ->return null else -> return obj } }
Kotlin还支持给函数参数默认值
fun init(a : Int = 1 ,b : Int = 2) : Int = a+b //如果不给a,b赋值,那么就使用默认值
for循环的使用
遍历items
val items = listOf<String>("apple","banana","orange","juice") for(i in items.indices){ println("item: ${items[i]}") //根据索引输入item }
或者这种形式
for(i in items){ println("item: $i") //直接输出item }
!! 和 ?.的含义
抛出NullPointerException异常使用 !!
var a : String?=null println(a!!.length)
安全调用操作符写作 ?. 使用这个符号会得到null的输出,还是这个例子,我们会打印null
var a : String?=null println(a?.length)
Kotlin 的类型系统旨在从我们的代码中消除 NullPointerException。NPE 可能的原因是
显式调用 throw NullPointerException()
使用了 !! 操作符
外部 Java 代码导致的
对于初始化,有一些数据不一致(如一个未初始化的 this 用于构造函数的某个地方)
安全的类型转换
如果对象不是目标类型,那么常规类型转换可能会导致 ClassCastException。 另一个选择是使用安全的类型转换,如果尝试转换不成功则返回 null:
val aInt: Int? = a as? Int
冒号 (:) 的作用
变量(常量)的声明 ,参数的声明,实现接口,方法返回值的声明 等作用
基础的语法大概就是这么多,接下来介绍一个比较推荐的东西——协程
协程
协程是什么?一些 API 启动长时间运行的操作(例如网络 IO、文件 IO、CPU 或 GPU 密集型任务等),并要求调用者阻塞直到它们完成。协程提供了一种避免阻塞线程并用更廉价、更可控的操作替代线程阻塞的方法:协程挂起。
协程通过将复杂性异步放入库来简化异步编程。程序的逻辑可以在协程中顺序地表达,而底层库会为我们解决其异步性。该库可以将用户代码的相关部分包装为回调、订阅相关事件、在不同线程(甚至不同机器!)上调度执行,而代码则保持如同顺序执行一样简单。
协程的具体实现
直接上代码
我们先进行一个简单的异步输出操作
fun main(args: Array<String>) = runBlocking<Unit>{ //创建主协程 var job = launch(CommonPool){ delay(1000) println("我是子协程,我延迟了一秒") } println("我是主协程,我先执行") delay(2000) println("我是主协程,我执行完了") }
我们看一下结果
这里的delay方法是一个挂起方法(suspend),它只能在协程中被调用,因为我们在main方法后面加了
fun main(args: Array<String>) = runBlocking<Unit< 4000 /span>>
因为main方法现在是一个协程,并且是主协程
那么这串代码就好理解了,我们开始先定义一个协程的任务,然后顺序执行,子协程运行的同时,主协程还在运行,在这个例子中子协程比主协程先运行完,所以如图上输出结果,但是还有一种情况是子协程需要运行的时间比主协程的长
fun main(args: Array<String>) = runBlocking{ //创建主协程 var job = launch(CommonPool){ delay(3000) println("我是子协程,我延迟了3秒") } println("我是主协程,我先执行") delay(1000) println("我是主协程,我执行完了") }
结果:
我们发现子协程里面的输出不见了,由此可见,子协程的执行时间是要小于主协程的,但有时我们又不知道子协程运行了多长时间怎么办,我们采用join方法
fun main(args: Array<String>) = runBlocking{ //创建主协程 var job = launch(CommonPool){ delay(3000) println("我是子协程,我延迟了3秒") } println("我是主协程,我先执行") job.join() println("我是主协程,我执行完了") }
这样我们就不用计算子协程需要运行的时间,但是如果我们想要取消子协程的任务怎么办,也很简单,只需要在主协程中加一条job.cancel()就能取消子协程
fun main(args: Array<String>) = runBlocking{ //创建主协程 var job = launch(CommonPool){ repeat(1000){ i -> println("我是子协程,我重复执行了 $i 次") delay(500) } } println("我是主协程,我先执行") delay(2000) println("我是主协程,我等不及了,你给我取消") job.cancel() println("我是主协程,我执行完了") }
结果:
但是cancel()并不是所有协程任务都能取消,比如下面这种情况就不能取消
fun main(args: Array<String>) = runBlocking{ //创建主协程 var job = launch(CommonPool){ var nextPrintTime = 0L var i = 0 while (i < 10) { // 循环运算 val currentTime = System.currentTimeMillis() if (currentTime >= nextPrintTime) { println("我是子协程,不能被取消,执行了 ${i++} 次") nextPrintTime = currentTime + 500L } } } println("我是主协程,我先执行") delay(1300L) println("我是主协程,我等不及了,你给我取消") job.cancel() delay(1300L) println("我是主协程,我执行完了") }
结果:
发现如果在进行循环操作的协程不能被取消,我们接下来取消循环运算协程
fun main(args: Array<String>) = runBlocking{ //创建主协程 var job = launch(CommonPool){ var nextPrintTime = 0L var i = 0 while (isActive) { // i<10改为 isActive 即可 val currentTime = System.currentTimeMillis() if (currentTime >= nextPrintTime) { println("我是子协程,不能被取消,执行了 ${i++} 次") nextPrintTime = currentTime + 500L } } } println("我是主协程,我先执行") delay(1300L) println("我是主协程,我等不及了,你给我取消") job.cancel() delay(1300L) println("我是主协程,我执行完了") }
结果:
关于协程的内容就介绍到这里,其他的以后再补充
相关文章推荐
- Android系统Recovery工作原理之使用update.zip升级过程分析(九)---updater-script脚本语法简介以及执行流程
- 搭建ELK(ElasticSearch+Logstash+Kibana)日志分析系统(二) Logstash简介及常见配置语法
- Android系统Recovery工作原理之使用update.zip升级过程分析(九)---updater-script脚本语法简介以及执行流程
- 词法分析与语法分析简介
- kotlin 语法分析(三) -- 类引用
- android中SELINUX规则分析和语法简介
- Android系统Recovery工作原理之使用update.zip升级过程分析(九)---updater-script脚本语法简介以及执行流程
- 使用Kotlin实现Android简单Demo,对比JAVA实现分析具体语法不同之处(一)
- 词法/语法分析框架 chrysanthemum 简介
- 【翻译】语法分析工具Gold介绍(1)——系统简介
- Android OTA升级原理和流程分析(九)---updater-script脚本语法简介以及执行流程
- Android系统Recovery工作原理之使用update.zip升级过程分析(九)---updater-script脚本语法简介以及执行流程
- Android系统Recovery工作原理之使用update.zip升级过程分析(九)---updater-script脚本语法简介以及执行流程
- 使用Kotlin实现Android简单Demo,对比JAVA实现分析具体语法不同之处(二)
- Android系统Recovery工作原理之使用update.zip升级过程分析(九)---updater-script脚本语法简介以及执行流程
- android中SELINUX规则分析和语法简介
- Android系统Recovery工作原理之使用update.zip升级过程分析(九)---updater-script脚本语法简介以及执行流程【转】
- Redy语法分析--简介
- Android OTA升级原理和流程分析(九)---updater-script脚本语法简介以及执行流程
- Android系统Recovery工作原理之使用update.zip升级过程分析(九)---updater-script脚本语法简介以及执行流程