名医指导 足不出户寻医问药
聚焦健康 权威的健康资讯
您的位置: 首页> 正文

两个this 一起用?Kotlin 的成员扩展函数和 implicit receiver

发布网友 发布时间:2024-10-24 12:56

我来回答

1个回答

热心网友 时间:2024-10-27 06:40

大家好,我是扔物线朱凯。

今天咱说说 Kotlin 的 implicit receiver。这是一个我们写 Kotlin 经常会用的东西,虽然你可能都没听过这个词,但你一定用过它。Kotlin 的很多高级功能,都利用到了这个概念——比如协程,协程是重度依赖它的,非常重。所以,弄明白它是个什么、怎么用、怎么去发挥它最大的价值,对我们的能力提升是非常有帮助的。

定义:其实隐式的接收器就是this。所谓的接收,其实指的就是接收调用,或者说接受调用。接受函数的调用啊,接受属性的访问啊。比如这个user.name:

左边的user 就是它的 receiver。谁的 receiver?对于 name 的访问的 receiver。

而隐式的 receiver,指的就是不用写也自动存在的 receiver。也就是如果我把这个user. 给删了,它依然能取到某个 User 对象的 name:

那么这个隐式地被应用的User 对象,就是对这个 name 的访问的 implicit receiver,隐式的 receiver。

嵌套的 implicit receiver 在 Kotlin 里是可以嵌套的,比如在 Java 里我们可以这么写:

我在这个内部类的里面,想访问内部类和外部类的成员都是可以的,是吧:

这个innerInt 是 InnerClass 里的,所以它等价于加上 this 的写法:

而下面的outerInt 属于外面的 OuterClass,但为了避免歧义,Java 不允许我们直接写 this:

而需要显式地加上OuterClass 的前缀:

而上面的innerInt 如果展开,前缀是 InnerClass:

也就是说,在内部类的里面,我是有内部类和外部类的双重this 的。对吧?

另外,对于它们同名的成员变量或者方法,如果我也省略掉this:

拿到的就是内部类的成员。如果想拿外部类的,就必须把this 写完整:

Kotlin 增加的 implicit receiver 嵌套:通过函数的 receiver 指定

然后,Kotlin 对于这种嵌套,又新增了一类场景——咱刚才看的是通过内部类来嵌套是吧?Kotlin 让我们还可以直接通过函数来嵌套新的this。比如你有一个在类型内部声明的扩展函数:

——这种函数叫 member extension function,成员扩展函数,其实就是字面意思:它既是成员函数又是扩展函数,对吧?

这种「成员扩展函数」有一个问题:一方面,因为它是Int 的扩展函数,所以你需要对 Int 类型的对象才能调用它;但同时,它也是 IntMultiplier 的成员函数,所以你还要求你对 IntMultiplier 对象调用它:

也就是说,这里需要的是个双重 receiver:既要这个直接的Int,又要那个外部的 IntMultiplier,缺一不可。——那我到底对谁调用?

Kotlin 提供的解法是,你专门创建一个函数,并给它设置一个函数类型的参数:

函数不用做什么特别的事,关键是执行一下它的那个函数类型的参数:

另外,你要给这个函数类型的参数,设置一个 receiver 的类型:

这么一指定,就把参数的函数体内部——注意,是这个block 的函数体,不是外部函数本身的函数体——在它内部强行安插了一个隐式的 receiver。换句话说,我在调用这个外部函数的时候,它的函数类型的参数的大括号里就有一个 IntMultiplier 类型的 this 了:

通过这种写法,我们就可以任意地往代码里插入我们指定的 implicit receiver,或者说指定的this,去应对「多个 this」的需求场景了。

协程里的应用

Kotlin 的官方代码,以及很多第三方库,都重度地依赖这个叫做 implicit receiver 的东西。虽然我们可以说「它不就是this 嘛」,但关键是,它给我们带来了很大的方便,怎么叫其实是次要的。随便举个例子,我们知道协程的启动是一定要用 CoroutineScope 才行的:

但是为什么在协程的内部再启动新的协程,就不用写CoroutineScope 了?

因为它有一个隐式的CoroutineScope 作为 this 被提供了:

总结

其他很多官方源码以及第三方库,都有类似的应用,而我们自己也可以在代码里用这样的写法去安插新的this 层级,或者说——安插 implicit receiver,隐式的 receiver。看起来好像很复杂,但当你明白它的这些本质逻辑,写起来就很简单了。
声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。
E-MAIL:11247931@qq.com
什么叫补按揭 后按揭贷款什么意思 买房者续按揭有什么危害 加按揭是什么意思 八月中国最凉快的地方 八月份哪里最凉快,去哪旅游好?美丽的地方 乱字同韵字是什么意思 华硕笔记本电脑触摸板怎么开笔记本电脑触摸板怎么开启和关闭_百度知 ... 陕西职务侵占案立案准则 结婚后我的恋情维系了十年,怎么做到的? 玉米仁子饭产自哪里 中国期货交易所的交易品种有哪些? 历史要怎么读,有啥诀窍 高中历史诀窍 年终会活动策划方案 深度解析:第一财经回放,探索财经新风向 逆水寒手游庄园怎么邀请好友同住 逆水寒手游 逆水寒不同区可以一起组队吗? 逆水寒手游 逆水寒怎么进入好友世界? 逆水寒手游 逆水寒怎么去别人的庄园? 使用puppeteer实现将htmll转成pdf 内卷时代下的前端技术-使用JavaScript在浏览器中生成PDF文档 【译】将HTML转为PDF的几种实现方案 变形金刚08动画怎么样 变形金刚08动画的问题 变形金刚08动画日语版剧情介绍 高分!换显卡nvidia控制面板被我卸了,重新安装显卡驱动后没了nvidia控... 我的nvidia控制面板被卸载了 怎么找回啊 卸载后 这个画面看着很奇怪_百 ... 李卓彬工作简历 林少明工作简历 广东工业职业技术学院怎么样 郑德涛任职简历 唐新桂个人简历 土地入股的定义 ups快递客服电话24小时 贷款记录在征信保留几年? 安徽徽商城有限公司公司简介 安徽省徽商集团新能源股份有限公司基本情况 安徽省徽商集团有限公司经营理念 2019哈尔滨煤气费怎么有税? 快手删除的作品如何恢复 体育理念体育理念 有关体育的格言和理念 什么是体育理念 万里挑一算彩礼还是见面礼 绿萝扦插多少天后发芽 绿萝扦插多久发芽 扦插绿萝多久发芽 炖牛排骨的做法和配料 网络诈骗定罪标准揭秘 全椒属于哪个省 利万高速重庆万州段 西双版纳傣族自治州民族教育条例第六章 教育工作者 HD1280 BD1024 都是mkv 哪个更好 驾照2014年3月14号到期,2013年能申请换证吗?特急谢 中行内蒙古长城常青树借记卡如何发卡? 如何快速清理地上油漆 我的驾驶证2013年8月28日到期,我想提前100多天申请换证可以吗??特急... BD1280高清.RMVB和 HD1024高清.MKV 哪个更清楚? 在开发中使用kotlin有什么奇巧淫技? Kotlin入门(27)文件读写操作 中国银行辽宁长城常青树借记卡开户办理流程 涂辣椒汁在身上可以减肥吗大神们帮帮忙 Kotlin入门(18)利用单例对象获取时间 西双版纳傣族自治州民族教育条例第八章 附则 西双版纳傣族自治州民族教育条例第三章 教育结构 全属强加10附首饰的宝珠叫什么名字 西双版纳傣族自治州民族教育条例第二章 管理体制 以柳絮为话题的作文,表现生命之轻 ...大千世界,芸芸众生,有谁不曾感到过累?有人为情所困而累,有人为... 西双版纳傣族自治州第二中学领导班子 公路工程技术标准内容简介 大家有没有办法解决老吕加油软件有余额加不了油客服不回应的事_百度知... 公路工程技术标准内容简介 手串顶珠和底珠的区别 原地面土需要做什么指标 路基施工前要做好哪些准备 路基施工前要做的准备简述 厦门大学哪个校区好玩一点? 河北省邯郸市某学校提前开学1个星期,怎样举报,谁有举报电话号码?急! 厦大哪个校区好 参观厦门大学哪个校区 家长举报邯郸某校向低分生收择校费?学校曾发严正声明不存在买分_百度知... 全椒县历史 厦门大学有几个校区及校区地址哪个校区最好 威尔姆·康拉德·伦琴【杂闻轶事】 新手买理财要注意什么 什么东西可以挡灰尘密封 购买冰箱你不能不知道的常识卫电器 冰箱的制冷方式哪种好冰箱使用注意事项卫电器 企业背景是什么
  • 焦点

最新推荐

猜你喜欢

热门推荐