当前位置:网站首页>Can't understand kotlin source code? Starting with the contracts function~
Can't understand kotlin source code? Starting with the contracts function~
2022-06-12 18:53:00 【Huanglinqing】
Preface
Recently, a friend reported that the source code is Kotlin, So I can't understand . Actually , Sometimes I can't understand Kotlin Probably because you don't know some specific syntax . Just as you don't understand the source code because you don't understand the design pattern ~
for instance
With Kotlin Commonly used isNullOrEmpty Methods as an example , The source code is shown below :
@kotlin.internal.InlineOnly
public inline fun CharSequence?.isNullOrEmpty(): Boolean {
contract {
returns(false) implies ([email protected] != null)
}
return this == null || this.length == 0
}
Why ? The code is simple , But I can't understand it ?contract What the hell is it ,implies What the hell is it ? In fact, when you understand contract After the use of the function , You can understand similar source code .
Contracts What is it? ?
Contracts It's a contract 、 Meaning of contract . from Kotlin1.3 Version was introduced , In a nutshell Contracts It can be used to solve some functions that the compiler cannot complete .
therefore , What on earth does it do ?
Let's define a similar function , Used to detect whether an object is null, So let's define a User object , The code is as follows :
data class User(val name: String, val age: Int)
Define another check User Whether the object is empty , The code is as follows :
fun isEmpty(user: User?) {
if (user == null) {
throw IllegalArgumentException("is empty")
}
}
Then we call... In the business method , The code is as follows :
fun work(user: User?){
isEmpty(user = user)
setText(user.name)
}
At this point, this method cannot be compiled , The compiler will remind you of user Is a nullable object , Need to add "?.",
But from our code logic , We first call isEmpty Method , If user The object is null Words , It's in isEmpty An exception has been thrown in the method , That is to say, it will not go to setText In the method . let me put it another way , If the code can be executed to setText In this business user The object must not be empty . So what to do now ? This requires Contracts Appearance. .
Contracts How to use
Contracts API It is generally shown as follows :
fun A() {
contract {
}
}
At present, the main methods of use are returns、callsInPlace etc. , First let's look at returns Usage scenarios of .
Returns Contracts
contract {
returns($value) implies($condition)
}
returns Used to tell the editor when the return value is value when condition Conditions established . At present value It can be Boolean or empty ,condition Conditional expressions also need to return Boolean types .
such as , Let's revise it now isEmpty Method , The code is as follows :
@ExperimentalContracts
fun isEmpty(user: User?) {
contract {
returns() implies (user != null)
}
if (user == null) {
throw IllegalArgumentException("is empty")
}
}
Here we go through contract Constraints tell the compiler , If isEmpty Function can return normally , It means that user Not empty . In other words, understand , That is to say, when user When it is empty, an exception is thrown , therefore isEmpty Function cannot return .
You'll find that , When it changes isEmpty After method ,work Methods no longer report errors .
This is because we have passed isEmpty Method tells the compiler , If code can be executed to setText, explain user The object must not be empty . Because this function is always experimental API, So add here @ExperimentalContracts annotation .
however , at present Kotlin This has been used in many source codes API, So we don't have to worry about big changes in the future . And then we'll see CallInPlace Usage scenarios of .
CallInPlace Contracts
CallInPlace Is also widely used , Let's say we have Kotlin Standard functions commonly used in apply、also etc. . Here we use apply Function as an example ,apply The source code of the function is as follows :
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
}
We can see from the source code that , It's used inside callsInPlace Method .callsInPlace You can tell the editor block Method is executed only once . instead of 0 Times or times . Of course, you can also set the method to execute at least once or at most once . This reader can try for himself .
Contracts Source code
So let's look at this first contract Source code of function , As shown below :
@ContractsDsl
@ExperimentalContracts
@InlineOnly
@SinceKotlin("1.3")
@Suppress("UNUSED_PARAMETER")
public inline fun contract(builder: ContractBuilder.() -> Unit) { }
contract It's an inline function , Need one ContractBuilder object , Then look ContractBuilder Object source code , As shown below :
@ContractsDsl
@ExperimentalContracts
@SinceKotlin("1.3")
public interface ContractBuilder {
@ContractsDsl public fun returns(): Returns
@ContractsDsl public fun returns(value: Any?): Returns
@ContractsDsl public fun returnsNotNull(): ReturnsNotNull
@ContractsDsl public fun <R> callsInPlace(lambda: Function<R>, kind: InvocationKind = InvocationKind.UNKNOWN): CallsInPlace
}
We can see returns Method returns Returns,callsInPlace Method returns CallsInPlace, and Returns The object is SimpleEffect The interface implements the self interface Effect,CallsInPalce The object is Effect Interface , The source code is shown below :
@ContractsDsl
@ExperimentalContracts
@SinceKotlin("1.3")
public interface SimpleEffect : Effect {
@ContractsDsl
@ExperimentalContracts
public infix fun implies(booleanExpression: Boolean): ConditionalEffect
}
@ContractsDsl
@ExperimentalContracts
@SinceKotlin("1.3")
public interface CallsInPlace : Effect
from SimpleEffect You can see in the source code , It implements a infix function named implies, To tell the compiler booleanExpression To be established , So as to agree with the compiler .
At the end
contract In fact, it is through an agreement with the compiler , It makes up for the shortcomings of intelligent transformation .
Some things may happen in the near future , To borrow “ Heart theory ” What the boss said today is —— 2022 year , It's a good thing ~
边栏推荐
- 一种灵活注入 Istio Sidecar 的方案探索
- Design of smart home control system (onenet) based on stm32_ two thousand and twenty-two
- Kali implements port forwarding through iptables
- The difference between user status and system status in CRM
- How to download Vega in China
- Why my order by create_ Time ASC becomes order by ASC
- MySQL数据库(28):变量 variables
- 实验10 Bezier曲线生成-实验提高-控制点生成B样条曲线
- 机器学习在美团配送系统的实践:用技术还原真实世界-笔记
- Dumi builds a document blog
猜你喜欢
leetcode:6097. 替换字符后匹配【set记录 + 相同长度逐一查询】
leetcode:98. 统计得分小于 K 的子数组数目【双指针 + 计算子集个数 + 去重】
leetcode:6096. 咒语和药水的成功对数【排序 + 二分】
吃饭咯 干锅肥肠 + 掌中宝!
Review of MySQL (VIII): Transactions
【图像去噪】基于正则化实现图像去噪附matlab代码
Mysql ->>符号用法 Json相关
leetcode:6095. 强密码检验器 II【简单模拟 + 不符合直接False】
CVPR 2022 oral Dalian Institute of technology proposed SCI: a fast and powerful low light image enhancement method
Free measurement of rectangular card [manual drawing ROI] Based on Halcon
随机推荐
Mysql ->>符号用法 Json相关
A fruitful afternoon
六石认知学:大脑的显速与潜速
Uniapp uses the Ali Icon
Review of MySQL (IX): index
kali2022如何安装w3af
kali局域网ARP欺骗(arpspoof)并监听(mitmproxy)局域内其它主机上网记录
Leetcode 416. Split equal sum subset
How to download Vega in China
Tarfile decompress nested tar
A story on the cloud of the Centennial Olympic Games belonging to Alibaba cloud video cloud
leetcode:6096. Success logarithm of spells and potions [sort + dichotomy]
In 2021, the global spice and seasoning revenue is about 18720million US dollars, and it is expected to reach 25960million US dollars in 2028
基于STM32设计智能家居控制系统(OneNet)_2022
MySQL - > > symbol usage JSON related
MySQL数据库(28):变量 variables
美团获得小样本学习榜单FewCLUE第一!Prompt Learning+自训练实战
【0008】无序列表
yoloe 目标检测使用笔记
基于Halcon的矩形卡片【手动绘制ROI】的自由测量