您的位置:首页 > 其它

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("我是主协程,我执行完了")

}


结果:



关于协程的内容就介绍到这里,其他的以后再补充
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  开发语言
相关文章推荐