Kotlin(3)-协程和操作符重载
println(“这是runBlocking协程…”)
launch {
println(“这是runBlocking内部的runBlocking协程…”)
delay(2000)
println(“延迟了2000MS之后,再打印”)
}
}
}
- GlobalScope.launch
fun main() {
println(“协程,相对于主线程来说,都是异步的,也就是说,你在这里插入协程逻辑,主线程的逻辑并不会被阻塞”)
GlobalScope.launch {
delay(3000)
println("GlobalScope.launch 创建协程 ")
}
println(“主线程继续”)
Thread.sleep(5000)
}
- Global.async
fun main() {
runBlocking {
val async: Deferred = GlobalScope.async {
println(“这是一个异步协程,他将返回一个Deferred”)
delay(2000)
“异步任务返回值”
}
println(“主线程继续:” + async.await())
}
Thread.sleep(5000)
}
“骚操作”
关心协程的人一般都会十分关注它到底能给我们异步编程带来怎样的便利。这里总结几个不用协程实现起来很麻烦的骚操作。
- 如果有一个函数,它的返回值需要等到多个耗时的异步任务都执行完毕返回之后,组合所有任务的返回值作为 最终返回值
fun test6(): String = runBlocking {
var finalRes = “”
coroutineScope {
launch {
delay(1000)
finalRes = finalRes.plus(“1”)
}
launch {
delay(2000)
finalRes = finalRes.plus(“2”)
}
launch {
delay(3000)
finalRes = finalRes.plus(“3”)
}
}
finalRes
}
fun main() {
val test6 = test6()
println(“最终返回值是: $test6”)
}
最终返回结果为(延迟3秒之后打印):
最终返回值是: 123
- 如果有一个函数,需要顺序执行多个网络请求,并且后一个请求依赖前一个请求的执行结果
import kotlinx.coroutines.*
suspend fun getToken(): String {
for (i in 0…10) {
println(“异步请求正在执行:getToken :$i”)
delay(100)
}
return “ask”
}
suspend fun getResponse(token: String): String {
for (i in 0…10) {
println(“异步请求正在执行:getResponse :$token $i”)
delay(100)
}
return “response”
}
fun setText(response: String) {
println(“setText 执行,时间: ${System.currentTimeMillis()}”)
}
fun main() {
GlobalScope.launch(Dispatchers.Unconfined) {
var token = GlobalScope.async(Dispatchers.Unconfined) {
return@async getToken()
}.await() // 创建异步任务,并且 阻塞执行 await 是阻塞执行取得结果
var response = GlobalScope.async(Dispatchers.Unconfined) {
return@async getResponse(token)
}.await() // 创建异步任务,并且立即执行
setText(response)
}
Thread.sleep(20000)
}
执行结果:
异步请求正在执行:getToken :0
异步请求正在执行:getToken :1
异步请求正在执行:getToken :2
异步请求正在执行:getToken :3
异步请求正在执行:getToken :4
异步请求正在执行:getToken :5
异步请求正在执行:getToken :6
异步请求正在执行:getToken :7
异步请求正在执行:getToken :8
异步请求正在执行:getToken :9
异步请求正在执行:getToken :10
异步请求正在执行:getResponse :ask 0
异步请求正在执行:getResponse :ask 1
异步请求正在执行:getResponse :ask 2
异步请求正在执行:getResponse :ask 3
异步请求正在执行:getResponse :ask 4
异步请求正在执行:getResponse :ask 5
异步请求正在执行:getResponse :ask 6
异步请求正在执行:getResponse :ask 7
异步请求正在执行:getResponse :ask 8
异步请求正在执行:getResponse :ask 9
异步请求正在执行:getResponse :ask 10
setText 执行,时间: 1578904290520
- 当前正在执行一项异步任务,但是你突然不想要它执行了,随时可以取消
fun main() {
// 协程任务
val job = GlobalScope.launch(Dispatchers.IO) {
for (i in 0…100){// 每次挂起100MS,100次也就是10秒
println(“协程正在执行 $i”)
delay(100)
}
}
// 但是我在1秒之后就取消协程
Thread.sleep(1000)
job?.cancel()
println( “btn_right 结束协程”)
}
执行结果(本该执行100轮的打印,只持续了10轮):
协程正在执行 0
协程正在执行 1
协程正在执行 2
协程正在执行 3
协程正在执行 4
协程正在执行 5
协程正在执行 6
协程正在执行 7
协程正在执行 8
协程正在执行 9
btn_right 结束协程
Process finished with exit code 0
- 如果你想让一个任务最多执行3秒,超过3秒则自动取消
import kotlinx.coroutines.*
fun main() = runBlocking {
println(“限时任务中结果是:” + getResFromTimeoutTask())
}
suspend fun getResFromTimeoutTask(): String? {
// 忘了,它会保证内部的协程代码都执行完毕,所以不能这么写
return withTimeoutOrNull(1300) {
for (i in 0…10) {
println(“I’m sleeping $i …”)
delay(500)
}
“执行结束”
}
}
执行结果
I’m sleeping 0 …
I’m sleeping 1 …
I’m sleeping 2 …
限时任务中结果是:null
Process finished with exit code 0
总结
协程作为kotlin 区别于java的新概念,它的出现是为了解决java不好解决的问题,比如层层回调导致代码臃肿,比如 异步任务执行流程不好操控等。本章节篇幅有限,无法展开说明,但是对于新手而言,看完本章应该能对协程的作用有一个大概的认知。本人也是初步研究,后续有更深入的了解之后,再进行专文讲解吧。
操作符重载
概念
说人话,像是一元操作符 ++自加,二元操作符 +相加 ,默认只支持数字类型,比如Int. 但是通过操作符的重载,我们可以让任意类 都能 ++自加,且返回一个想要的对象。操作符执行的逻辑,完全看我们如何去设计。
分类
按元素级别
- 一元
| 表达式 | 对应函数 |
|---|---|
| +a | a.unaryPlus() |
| -a | a.unaryMinus() |
| !a | a.not() |
| a++ | a.inc() |
| a– | a.dec() |
- 二元
| 表达式 | 对应函数 |
|---|---|
| a+b | a.plus(b) |
| a-b | a.minus(b) |
| a*b | a.times(b) |
| a/b | a.div(b) |
| a%b | a.rem(b) |
| a…b | a.range(b) |
| a in b | b.contains(a) |
| a !in b | !b.contains(a) |
| a[i] | a.get(i) |
| a[i,j] | a.get(i,j) |
| a[i_1,…,i_n] | a.get(i_1,…,i_n) |
| a[i]=b | a.set(i,b) |
| a[i,j]=b | a.set(i,j,b) |
| a[i_1,…,i_n]=b | a.set(i_1,…,i_j,b) |
| a() | a.invoke() |
| a(i) | a.invoke(i) |
| a(i,j) | a.invoke(i,j) |
| a(i_1,…,i_n) | a.invoke(i_1,…,i_n) |
| a+=b | a.plusAssign(b) |
| a-=b | a.minusAssign(b) |
| a*=b | a.timesAssign(b) |
| a/=b | a.divAssign(b) |
| a%=b | a.modAssign(b) |
| a > b | a.compareTo(b)>0 |
| a < b | a.compareTo(b)<0 |
| a>=b | a.compareTo(b)>=0 |
| a<=b | a.compareTo(b)<=0 |
按实现方式
-
成员函数
-
扩展函数
栗子
看到上面的一大堆,肯定有点懵,看个例子解决疑问。上面我用两种维度来对操作符重载进行了分类,那么,先试试:成员函数的方式来重载一个一元操作符
class A(i: Int, j: Int) {
var i: Int = i
var j: Int = j
/**
- 重载++操作
*/
operator fun inc(): A {
return A(i++, j++)
}
override fun toString(): String {
return “[i= i , j = i , j= i,j=j]”
}
}
如上代码,注意看:
operator fun inc(): A {
return A(i++, j++)
}
Kotlin的操作符重载和 c++,dart语言内的操作符重载写法完全不同,它不再是直接把操作符放到了 重写的过程中,而是每一种支持重载的操作符都有一个对应的 函数名
正如:上表格中的 a++ 操作符,对应的函数就是 a.inc()
调用的时候:
fun main() {
var a = A(1, 2)
println(“a:
a
"
)
p
r
i
n
t
l
n
(
"
a
+
+
:
a") println("a++:
a")println("a++:{a++}”)
}
打印结果:
a:[i=1 , j=2]
a++:[i=2 , j=3]
再看一个二元运算符重载的栗子,这次我们不用成员函数,而是用扩展函数:
class A(i: Int, j: Int) {
var i: Int = i
var j: Int = j
override fun toString(): String {
return “[i=
i
,
j
=
i , j=
i,j=j]”
}
}
/**
- 重载A类的 x+y 操作
*/
operator fun A.plus(a: A): A {
return A(this.i + a.i, this.j + a.j)
}
fun main() {
val x = A(1,1)
val y = A(2,2)
println(x+y)
}
这里演示的是 A类的 x+y 操作符重载。细节应该不用多说。
打印结果:
[i=3 , j=3]
再来一个较为复杂的栗子, 重载 a[i]
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。





既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
文末
很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,对此我整理了一些资料,需要的可以免费分享给大家
这里笔者分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。


【视频教程】

天道酬勤,只要你想,大厂offer并不是遥不可及!希望本篇文章能为你带来帮助,如果有问题,请在评论区留言。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
[外链图片转存中…(img-JQC2LnLG-1712776269167)]
[外链图片转存中…(img-ITnVluq5-1712776269167)]
【视频教程】
[外链图片转存中…(img-gnmmxjfV-1712776269168)]
天道酬勤,只要你想,大厂offer并不是遥不可及!希望本篇文章能为你带来帮助,如果有问题,请在评论区留言。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
更多推荐

所有评论(0)