当前位置:网站首页>Kotlin1.6.20 new features context receivers tips
Kotlin1.6.20 new features context receivers tips
2022-06-22 20:32:00 【1024 Q】
Preface
Limitations of extension functions
What is? Context Receivers
How to use Context Receivers
introduce Context Receivers Cause readability problems
Context Receivers Application scope and precautions
summary
PrefaceLet's talk about this article Kotlin 1.6.20 New functions Context Receivers, Let's see what problems it solves for us .
Through this article, you will learn the following :
Limitations of extension functions
What is? Context Receivers, And how to use it
Context Receivers What problems have been solved
introduce Context Receivers It will bring new problems , How do we solve
Context Receivers Application scope and precautions
Limitations of extension functionsstay Kotlin The receiver in can only be applied to the extension function or with the receiver lambda Expression , As shown below .
class Context { var density = 0f}// spread function inline fun Context.px2dp(value: Int): Float = value.toFloat() / densityThe recipient is fun After keyword and Type before point Context, There are two knowledge points hidden here .
We can call an internal function , Call the extension function px2dp(), Usually combined with Kotlin Scope function with , run , apply And so on .
with(Context()) { px2dp(100)}Inside the extension function , We can use this keyword , Or hide keywords and implicitly access internal member functions , But we can't access private members
Extension functions are easy to use , We can extend the system or third-party library , But there are limitations .
Only one recipient can be defined , Therefore, its composability is limited , If there are multiple recipients, they can only be passed as parameters . Let's say we call px2dp() Method at the same time , Go to logcat and file Write log in .
class LogContext { fun logcat(message: Any){}}class FileContext { fun writeFile(message: Any) {}}fun printf(logContext: LogContext, fileContext: FileContext) { with(Context()) { val dp = px2dp(100) logContext.logcat("print ${dp} in logcat") fileContext.writeFile("write ${dp} in file") }}stay Kotlin The receiver in can only be applied to the extension function or with the receiver lambda Expression , But it can't be used in ordinary functions , Lost flexibility
Context Receivers The emergence of brings new possibilities , It's a combination , Merge multiple context recipients together , More flexibility , Wider application .
What is? Context ReceiversContext Receivers Used to represent a basic constraint , That is, things that need to be done within certain scope under certain circumstances , It's more flexible , It can be combined , Organizational context , Group systems or third-party classes together , More functions .
If you want to use Context Receivers, Need to put Kotlin Plug in upgrade to 1.6.20 , And it can only be used after it is opened in the project .
plugins { id 'org.jetbrains.kotlin.jvm' version '1.6.20'}// ......kotlinOptions { freeCompilerArgs = ["-Xcontext-receivers"]} How to use Context ReceiversWhen we finish the above configuration , You can use Context Receivers, Now let's transform the above case .
context(LogContext, FileContext)fun printf() { with(Context()) { val dp = px2dp(100) logContext.logcat("print ${dp} in logcat") fileContext.writeFile("write ${dp} in file") }}We are printf() On the function , Use context() keyword , stay context() Keywords in parentheses , Declare a list of context recipient types , Multiple types are separated by commas . However, the types listed cannot be repeated , No subtype relationship is allowed between them .
adopt context() Keyword to limit its scope , In this function , We can call context LogContext 、 FileContext Internal methods , But when it's used , Only through Kotlin Scope functions are nested to pass multiple recipients , Maybe in the future, it may provide a more elegant way .
with(LogContext()) { with(FileContext()) { printf("I am DHL") }} introduce Context Receivers Cause readability problems If we were LogContext and FileContext Multiple variables or functions with the same name are declared in , We can only pass [email protected] To solve this problem .
context(LogContext, FileContext)fun printf(message: String) { logcat("print message in logcat ${[email protected]}") writeFile("write message in file ${[email protected]}")}As you can see , stay LogContext and FileContext One of them is called name The variable of , We can only pass [email protected] Statement to access , But this will introduce a new problem , If there are a large number of variables or functions with the same name , It can lead to this Keywords are scattered everywhere , Resulting in poor readability . So we can isolate through the interface , To solve this problem .
interface LogContextInterface{ val logContext:LogContext}interface FileContextInterface{ val fileContext:FileContext}context(LogContextInterface, FileContextInterface)fun printf(message: String) { logContext.logcat("print message in logcat ${logContext.name}") fileContext.writeFile("write message in file ${fileContext.name}")}By means of interface isolation , We can solve this The problem of poor readability caused by keywords , When using, you need to instantiate the interface .
val logContext = object : LogContextInterface { override val logContext: LogContext = LogContext()}val fileContext = object : FileContextInterface { override val fileContext: FileContext = FileContext()}with(logContext) { with(fileContext) { printf("I am DHL") }}Context Receivers Application scope and precautions When we rewrite a function with a context acceptor , Must be declared as a context recipient of the same type .
interface Canvasinterface Shape { context(Canvas) fun draw()}class Circle : Shape { context(Canvas) override fun draw() { }}We rewrote draw() function , The context recipient of the declaration must be the same ,Context Receivers It can not only act on the extension function 、 On ordinary functions , And it can also act on classes .
context(LogContextInterface, FileContextInterface)class LogHelp{ fun printf(message: String) { logContext.logcat("print message in logcat ${logContext.name}") fileContext.writeFile("write message in file ${fileContext.name}") }}In the class LogHelp It has been used. context() keyword , We can do that LogHelp Use anywhere in the range LogContext perhaps FileContex.
val logHelp = with(logContext) { with(fileContext) { LogHelp() }}logHelp.printf("I am DHL")Context Receivers In addition to acting on extension functions 、 Ordinary function 、 Class , It can also act on attributes getter and setter as well as lambda On the expression .
context(View)val Int.dp get() = this.toFloat().dp// lambda expression fun save(block: context(LogContextInterface) () -> Unit) {}Finally, let's take a look , From the community Context Receivers Practical cases , Expand Json Tool class .
fun json(build: JSONObject.() -> Unit) = JSONObject().apply { build() }context(JSONObject)infix fun String.by(build: JSONObject.() -> Unit) = put(this, JSONObject().build())context(JSONObject)infix fun String.by(value: Any) = put(this, value)fun main() { val json = json { "name" by "Kotlin" "age" by 10 "creator" by { "name" by "JetBrains" "age" by "21" } }} summary Context Receivers Provide a basic constraint , It can be within the specified range , Realize more functions through combination
Context Receivers Can act on extension functions 、 Ordinary function 、 class 、 attribute getter and setter 、 lambda expression
Context Receivers Allows you to... Without inheritance , By combination , Organizational context , Group systems or third-party classes together , More functions
adopt context() Keyword declaration , stay context() Keywords in parentheses , Declare a list of context recipient types , Multiple types are separated by commas
If used in large quantities this Keywords can lead to poor readability , We can solve this problem through interface isolation
When we rewrite a function with a context acceptor , Must be declared as a context recipient of the same type
That's all Kotlin1.6.20 function Context Receivers Details of using skills to uncover secrets , More about Kotlin1.6.20 function Context Receivers Please pay attention to other relevant articles of software development network !
边栏推荐
- IVX no code challenge five second game production
- web技术分享| 【高德地图】实现自定义的轨迹回放
- Cloud computing in the metauniverse to enhance your digital experience
- 防火墙基础之安全策略和NAT(Easy IP)
- Stochastic Adaptive Dynamics of a Simple Market as a Non-Stationary Multi-Armed Bandit Problem
- [in depth understanding of tcaplus DB technology] getting started tcaplus SQL driver
- Teach you how to create SSM project structure in idea
- [in depth understanding of tcaplus DB technology] Introduction to tcaplus JDBC development
- I wrote a telnet command myself
- 【Proteus仿真】NE555延时电路
猜你喜欢

防火墙基础之安全策略和NAT(Easy IP)

Please describe the whole process from entering a URL in the browser to rendering the page.
![[deeply understand tcapulusdb knowledge base] common problems in deploying tcapulusdb local](/img/2b/3ab5e247ac103728b4d3579c3c5468.png)
[deeply understand tcapulusdb knowledge base] common problems in deploying tcapulusdb local

【深入理解TcaplusDB技术】入门Tcaplus SQL Driver

web技术分享| 【高德地图】实现自定义的轨迹回放

ZABBIX learning notes (37)

【深入理解TcaplusDB知識庫】部署TcaplusDB Local版常見問題

采用QTest进行数据集测试-性能测试-GUI测试

【深入理解TcaplusDB技术】TcaplusDB 表管理——清理表

【Proteus仿真】74LS138译码器流水灯
随机推荐
Random talk about redis source code 122
CVPR 2022 oral | video text pre training new SOTA, HKU and Tencent arc lab launched excuse task based on multiple-choice questions
如何低成本快速搭建企业知识库?
模拟串口UART的实现
Recv function with timeout
Three dimensional world helps the laboratory to consolidate the complete quality system management
他98年的,我玩不过他...
Redis持久化的几种方式——深入解析RDB
NFT 中可能存在的安全漏洞
510000 prize pool invites you to join the war! The second Alibaba cloud ECS cloudbuild developer competition is coming
An IPFs enabled email - skiff
[deeply understand tcapulusdb technology] tcapulusdb table management - clean up table
【深入理解TcaplusDB技术】入门Tcaplus SQL Driver
数字化转型的失败原因及成功之道
Can financial products be redeemed on weekends?
Zabbix学习笔记(三十七)
[deeply understand tcapulusdb technology] tcapulusdb table management - rebuild table
6月第3周B站榜单丨飞瓜数据UP主成长排行榜(哔哩哔哩平台)发布!
三维天地助力实验室夯实完整质量体系管理
R语言数据预处理、把类型变量转化为因子变量,把数据集转化为h2o格式、数据集划分(训练集、测试集、验证集)