在使用kotlin协程时,突然发现一个无法理解的语法。

在下图中,是runBlocking的源代码

可以发现,他需要接受两个参数,第一个是context,第二个则是我们自己的lambda函数。
而实际上,我们并没用传入第一个参数进去,他却可以正常的运行而不报错。他也并没有默认的参数。

解释

首先我们要理解的是kotlin是个多平台支持的语言。因此他在实现某些功能时,需要兼容win,linux,java等多平台。
例如:我们正在使用的协程库,肯定是一个多平台库。

expect actual

Kotlin中的expect和actual是一对关键字,用于实现跨平台的编程,特别是在编写多平台库(Commons Kt)时。在这种情况下,我们需要在一个公共的Kotlin文件中定义接口和类,而实现则需要针对不同的平台进行特殊处理,因为不同平台的操作系统和硬件配置有所不同。

expect和actual关键字是为了解决这种情况而设计的。expect用于声明一个接口或类,以及其所需要的属性和方法;而actual则用于提供这个接口或类的实际实现。这种技术可以让我们以一种抽象的方式编写代码,而不用关心它在不同平台上的实现细节。

例如,在Commons Kt中,我们可能需要实现一个网络请求的框架。在这种情况下,我们可以使用expect来定义一个接口:

1
2
3
4
expect interface HttpClient {
fun get(url: String): String
fun post(url: String, data: String): String
}

接下来,在各个平台的特定实现中,我们可以使用actual关键字提供具体的实现:

1
2
3
4
5
6
7
8
9
actual class HttpClientImpl : HttpClient {
override fun get(url: String): String {
// 在Android平台上使用OkHttp来实现
// 在iOS平台上使用NSURLSession来实现
}
override fun post(url: String, data: String): String {
// 实现与get()方法类似
}
}