关于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啦~

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Java Swing 图形界面开发(目录)

    JavaSwing图形界面(GUI)开发基础教程(目录)

  • 《QTreeView+QAbstractItemModel自定义模型》:系列教程之三[通俗易懂]

    《QTreeView+QAbstractItemModel自定义模型》:系列教程之三[通俗易懂]1、了解常用的model类通过对上一节的阅读,我们知道只要具备model+view就可以显示数据。那么有哪些model类呢,从下图中我们可以看到Qt中模型类的层次结构QStandardItemModel:可以作为QListView、QTableView、QTreeView的标准model。QAbstractListModel:需要使用QListView显示数据,并配合自定义…

  • 常见的路由协议「建议收藏」

    常见的路由协议「建议收藏」常见的路由协议可以分为两种类型一、内部网关协议内部网关协议(IGP:InteriorGatewayProtocol),适用于单个ISP的统一路由协议的运行,一般由一个ISP运营的网络位于一个AS(自治系统)内,有统一的ASnumber(自治系统号),用来处理内部路由。RIP、IGRP(Cisco私有协议)、EIGRP(Cisco私有协议)、OSPF、IS-IS等都是内部网关协议。1、…

    2022年10月22日
  • UART 和 USART 有区别

    UART 和 USART 有区别UART:universalasynchronousreceiverandtransmitter通用异步收发器          [BusSignal]  TX ,RX USART:universalsynchronousasynchronousreceiverandtransmitter通用同步异步收发器          [BusSignal]  T

  • Java之Lambda表达式详解

    Java之Lambda表达式详解Lambda表达式,也可称为闭包,它是推动Java8发布的最重要新特性。Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用Lambda表达式可以使代码变的更加简洁紧凑。一、lambda表达式的语法格式如下:标准格式:(形式参数)->{代码块}Lambda表达式的代码分析●():里面没有内容,可以看成是方法形式参数为空●->:用箭头指向后面要做的事情●{}:包含一段代码,我们称之为代码块,可以看成是方法体中的内容实例.

  • 在线IEEE浮点二进制计算器工具「建议收藏」

    在线IEEE浮点二进制计算器工具「建议收藏」在线IEEE浮点二进制计算器工具在线IEEE浮点二进制计算器工具这是一个小计算器,旨在帮助您了解用于浮点计算的IEEE754标准。它是用JavaScript实现的,并且可以与Chrome和Firefox的最新桌面版本一起使用。我尚未在其他浏览器上进行过测试。如果您在左侧的三个框中之一中输入浮点数字,然后按Enter键,您将在右侧看到该数字的位模式。您可以输入使用通常在编程语言接受的语法,比如数字42,2.345,12E-3,等;您可以输入值NaN,Inf和-Inf直接;并且您还可以使用语法输入分

    2022年10月20日

发表回复

您的电子邮箱地址不会被公开。

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