关于Kotlin扩展函数与lambda的上下文

关于Kotlin扩展函数与lambda的上下文

大家好,又见面了,我是全栈君。

通常我们在写一个扩展函数,如果传入一个lambda表达式大概是下面这样

inline fun <T> T.apply(block: () -> Unit) {
    block()
}
复制代码

这个时候它的上下文是谁呢?

在扩展的方法内部,这个方法的上下文其实就是这个T,也就是调用这个方法的对象,所以this == T,这一点很明显。

那么在外部使用的时候,如下代码中呢?

val textView = TextView(activity).apply {
    //这里的上下文是谁呢?
}
复制代码

注意,这里虽然调用了apply方法,但是后面的代码块{}实际上是block: () -> Unit这个lambda的简写,也就是说我们是处于一个lambda表达式中,所以它的上下文自然就是这段代码外部的上下文。可能是activity,也可能是别的什么东西。我最初在这里卡了一会儿,就是不小心把这里也当做了扩展的内部,纠结于为毛这里不能拿到这个TextView对象。

但是我们知道Kotlin自己带的apply方法是可以在这个lambda中去拿到调用它的对象,然后去做一些配置操作的,也就是说是可以把这个lambda中的上下文变成调用者的。怎么做呢?

其实很简单,将apply中的那个lambda也变成调用者的一个扩展方法就行了。像下面这样写。

inline fun <T> T.apply(block: T.() -> Unit) {
    block()
}
复制代码

这里可以看到我给把这个lambda变成了T.()->Unit,表示它是T的一个扩展方法。既然这个lambda一家是T的一个扩展方法了,那么他内部的上下文自然就是这个T了。所以就可以有了如下的写法。

TextView(activity).apply {
    text = "HelloDSl"
    textSize = 16.sp2px()
}
复制代码

是不是已经和Kotlin自己的apply方法几乎一样了,但是既然apply是用来快速构造对象的,那么自然需要它能将调用它的对象返回回来,所以加上返回值就变成了下面这样。

inline fun <T> T.apply(block: T.() -> Unit): T {
    block()
    return this
}
复制代码
val textView = TextView(activity).apply {
    text = "HelloDSl"
    textSize = 16.sp2px()
}
复制代码

那么这个东西有什么用处呢? 有了它就可以轻松写出一个DSL啦~

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/107736.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pycharm2021专业版激活码【最新永久激活】

    (pycharm2021专业版激活码)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~1STL…

    2022年3月27日
    1.1K
  • asp中的session使用方法详解

    asp中的session使用方法详解ASP中: SESSION必须倚赖COOKIE才可用,SESSION是存储在服务器端的,而COOKIE是存储在客户端的,相对而言,SESSION的安全性和可靠程度都比COOKIE高 ASP.NET中 SESSION可以不依赖COOKIE而存在!!! 也就是说,从微软的方面来说,开始让SESSION摆脱COOKIE的束缚了!!Session数据是存储在服务器上的,C

    2022年7月15日
    16
  • Windows下cmd进入MySql的命令界面

    Windows下cmd进入MySql的命令界面####win+R快捷键打开运行,输入cmd,进入cmd若未将MySql加入环境变量,切换到mysql的安装目录下的bin目录;若已加入环境变量,则不必切换目录。输入主机名、数据库名、密码mysql-hlocalhost-uroot-p输入数据库密码

    2022年6月4日
    27
  • tabnine激活(JetBrains全家桶)「建议收藏」

    (tabnine激活)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html4M7HSKPBXS-eyJsaWN…

    2022年3月29日
    541
  • ContentMode 几个属性

    ContentMode 几个属性

    2022年1月8日
    37
  • CAN总线详解

    1、简介CAN是控制器局域网络(ControllerAreaNetwork,CAN)的简称,是一种能够实现分布式实时控制的串行通信网络。优点:传输速度最高到1Mbps,通信距离最远到10km,无损位仲裁机制,多主结构。近些年来,CAN控制器价格越来越低。Ø低成本:ECUs通过单个CAN接口进行通信,布线成本低。Ø高集成:CAN总线系统允许在所有ECUs上进行集中错误诊…

    2022年4月6日
    81

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号