Kotlin新特性:Context receivers将被废弃
The following article is from Android技术圈 Author 黄林晴
前言
在7月30日发布的Kotlin 2.0.20-RC版本特性中,主要强调了一些功能改进,如:
支持2.0.20-RC 的 Kotlin 插件捆绑在最新的 IntelliJ IDEA 和 Android Studio 中。
Data Class copy()函数具有与构造函数相同的可见性。
逐步废弃Context receivers特性。
Kotlin 跨平台以及Kotlin Native的一些改进。
Context receivers是在 Kotlin 1.6.20中版本中引入的,主要用来解决扩展函数只有一个上下文局限性的问题。
这个API虽然一直是实验性的,但是官方考虑到有很多开发者已经使用,所以Kotlin也不会在2.0.20版本中直接废弃,而是会逐步弃用,推荐使用Context parameters来代替,所以后续新功能我们就不要再使用Context receivers了。
当我们在2.0.20-RC版本中继续使用Context receivers时,编译器将会出现警告。
class MyContext
context(MyContext)
// warning: experimental context receivers are deprecated and will be superseded by context parameters.
// Please don't use context receivers. You can either pass parameters explicitly or use members with extensions.
fun someFunction() {
}
那我们可以怎么做呢?官方建议我们通过明确参数或者扩展成员函数的方式来实现。
明确参数
原代码如下所示:
context(ContextReceiverType)
fun someFunction() {
contextReceiverMember()
}
修改后的代码如下所示:fun someFunction(explicitContext: ContextReceiverType) {
explicitContext.contextReceiverMember()
}
好家伙,这不又回到了传参的方式,当初介绍Context receivers优势时可也是这个例子 。
扩展成员函数
原代码如下所示:
context(ContextReceiverType)
fun contextReceiverMember() = TODO()
context(ContextReceiverType)
fun someFunction() {
contextReceiverMember()
}
修改之后的代码如下所示:
class ContextReceiverType {
fun contextReceiverMember() = TODO()
}
fun ContextReceiverType.someFunction() {
contextReceiverMember()
}
接着我们来看看官方推荐的Context parameters是个啥?
2关于 Context parameters目前Koltin官方文档中还没有对Context parameter的介绍,我们只能从github链接中找到。里面的东西比较多,并且当前还不稳定,我们只来看如何声明Context parameter。
如何声明Context parameters
Context parameters 用 context 关键字声明,后跟一个参数列表,每个参数的形式名称为: Type,代码如下所示:
interface Type {
context(analysisScope: AnalysisScope)
val isNullable: Boolean = ...
}
context(analysisScope: AnalysisScope)
fun Type.equalTo(other: Type): Boolean = ...
context(_: AnalysisScope)
val Type.isBoolean: Boolean get() = this.equalTo(BuiltIns.Boolean)
同时属性也是支持Context parameters的,用法如下所示:
context(users: UserRepository)
val firstUser: User? get() = users.getById(1)
同时Context parameters也是隐式的,因为当调用带有Context parameters的函数或属性时,这些参数并不会被明确列出,如:
context(logger: Logger) fun logWithTime(message: String) =
logger.log("${LocalDateTime.now()}: $message")
context(logger: Logger) fun User.doAction() {
logWithTime("saving user $id")
// ...
}
从这里来看,感觉Context parameters和Context receivers没啥区别,可以说是写法变了而已,但是官方肯定会列出来一些优势,但是仍然不影响Context parameters以后被废弃。3思考
Context receivers这么快就被废弃是值得我们思考的,Context receivers当初解决的问题无非就是少声明一个参数的问题,是否有必要为了图一时之快而留后患。就像我们现在使用Kotlin语法糖一样,很多基础方法都忘了。
说了这么多,不得不感叹一句:幸亏我没用Context receivers。
最后推荐一下我做的网站,玩Android: wanandroid.com ,包含详尽的知识体系、好用的工具,还有本公众号文章合集,欢迎体验和收藏!
推荐阅读:
LeakCanary 你真的了解么?看看这些高级用法
详解Android14 Activity 启动过程
扫一扫 关注我的公众号
如果你想要跟大家分享你的文章,欢迎投稿~
┏(^0^)┛明天见!