一.Kotlin 协程启动方式总结
1.withContext 同步串行 带返回
2.launch 异步 不带返回
3.asyc 异步 带返回
4.runblocking 同步 带返回
二.作用域函数 ,T的扩展函数 (with不是T的扩展函数)都是内联函数
Kotlin中的lateinit和by lazy有以下几个区别:
by lazy { … } 只能被用在被val修饰的变量上,而lateinit只能被用var修饰的变量上。
lateinit 不能用在可空的属性上和Java的基本类型上,但 by lazy { … } 可以。
lateinit 可以在任何位置初始化并且可以初始化多次,而 by lazy { … } 在第一次被调用时就被初始化,想要被改变只能重新定义。
lateinit 有支持(反向)域(Backing Fields),但 by lazy { … } 没有。
三.协程作用域 :
1.顶级作用域
在 Android 中,某些 KTX 库为某些生命周期类提供自己的 CoroutineScope。主要有以下4种:
GlobeScope:全局范围,不会自动结束执行。
MainScope:主线程的作用域,全局范围
lifecycleScope:生命周期范围,用于activity等有生命周期的组件,在Desroyed的时候会自动结束。
viewModeScope:ViewModel范围,用于ViewModel中,在ViewModel被回收时会自动结束
所有的Scope都是 CoroutineScope 的子类。以上4种可以认为是最顶级的协程作用域,能在Activity、Fragment、ViewModel等类的 普通函数中 直接调用
2. coroutineScope & 3.supervisorScope
这两个就是2个挂起函数,分别表示协同作用域和主从作用域,因为是挂起函数所以也必须在协程块或挂起函数内调用:
private fun request() {
lifecycleScope.launch {
coroutineScope { // 协同作用域,抛出未捕获异常时会取消父协程
launch { }
}
supervisorScope { // 主从作用域,抛出未捕获异常时不会取消父协程
launch { }
}
}
}
二者的区别:
supervisorScope 表示主从作用域,会继承父协程的上下文,它的特点就是子协程的异常不会影响父协程,内部的 子协程挂掉 不会影响外部的父协程和兄弟协程的继续运行,它就像一道防火墙,隔离了异常,保证程序健壮,但是如果外部协程挂掉还是可以取消子协程的,即 单向传播。它的设计应用场景多用于 子协程为独立对等的任务实体的时候,比如一个下载器,每一个子协程都是一个下载任务,当一个下载任务异常时,它不应该影响其他的下载任务。
coroutineScope 表示 协同作用域, 内部的协程 出现异常 会向外部传播,子协程未捕获的异常会向上传递给父协程, 子协程 可以挂掉外部协程 , 外部协程挂掉也会挂掉子协程,即 双向传播 。 任何一个子协程异常退出,会导致整体的退出。
Kotlin中Any、Nothing、Unit 类型的概念和用法
Any类型
Any 是 Kotlin 类层次结构的根。每个 Kotlin 类都将 Any 作为其父类。这意味着 Any 是你在 Kotlin 中定义的任何类的父类,它与 Java 中的 Object 完全等效。
下面是 Any 类的定义:
public open class Any {
/**
* 判断某个对象是否与当前对象相等。
*/
public open operator fun equals(other: Any?): Boolean
/**
* 返回对象的哈希码值。hashCode 的一般约定是:
*
*/
public open fun hashCode(): Int
/**
* 返回对象的字符串表示。
*/
public open fun toString(): String
}
在上面的示例中,可以看到 Any 类提供了 equals、hashCode 和 toString 方法。这些方法可以在任何 Kotlin 类中使用,因为每个类都是 Any 类的子类。
Nothing 类型
在 Kotlin 中,可以使用 Nothing 类型表示“永远不存在的值”。例如,如果一个函数的返回类型为 Nothing,那么它意味着该函数永远不会返回(总是抛出异常)。
下面是 Nothing 类型的定义:
public class Nothing private constructor() {
// Nothing 类没有实例
}
上面的定义意味着你无法实例化这个类,也意味着没有其他类可以继承它。
以下是一个使用 Nothing 的函数示例,该函数总是抛出异常,永远不会返回任何值:
fun error(message: Any): Nothing {
throw IllegalStateException(message.toString())
}
上述函数始终抛出异常,不会返回任何值。需要注意的是,必须明确指定 Nothing 作为返回类型,否则返回类型仍然是 Unit。
Unit 类型
Unit 类型是只有一个值的类型,即 Unit 对象。这个类型对应于 Java 中的 void 类型。
以下是 Unit 类型的定义:
public object Unit {
override fun toString() = “kotlin.Unit”
}
在 Kotlin 中,如果你没有显式指定函数的返回类型,那么函数的默认返回类型是 Unit。这意味着如果函数的返回类型没有显式指定,Kotlin 编译器将使用 Unit 作为返回类型。
下面的示例展示了两个行为相似的函数:
fun display() {
print(“kotlin”)
}
fun display(): Unit {
print(“kotlin”)
}
在上面的示例中,这两个函数的行为是相似的。如果没有指定返回类型,Kotlin 编译器会将其默认设置为 Unit。
那么提问Kotlin中的void和Unit的区别是什么?
答:结构不同,void是一个java关键字,而Unit在kotlin中是一个真实的object,Java中要求函数必须有返回值,当什么都不返回时可以使用void,而kotlin中也可以返回Unit,从这个角度来说kotlin的Unit相当于java中的Void,但在kotlin中 默认都是返回Unit并且可以省略。