Kotlininline扩展函数

更新时间:2023-07-15 04:38:18 阅读: 评论:0

Kotlininline扩展函数
Kotlin 内联扩展函数之 let also run apply with
简介:
在Kotlin中的源码标准库()中提供了⼀些Kotlin扩展的内置函数可以优化kotlin的编码。Standard.kt是Kotlin库的⼀部分,它定义了⼀些基本inline函数。在c/c++中,为了解决⼀些频繁调⽤的⼩函数⼤量消耗栈空间(栈内存)的问题,特别的引⼊了inline修饰符,表⽰为内联函数。栈空间就是指放置程序的局部数据(也就是函数内数据)的内存空间。
lambda表达式:
lambda表达式的本质其实是匿名函数,因为在其底层实现中还是通过匿名函数来实现的。但是我们在⽤的时候不必关⼼起底层实现。不过Lambda的出现确实是减少了代码量的编写,同时也是代码变得更加简洁明了。Lambda作为函数式编程的基础,其语法也是相当简单的。这⾥先通过⼀段简单的代码演⽰没让⼤家了解Lambda表达式的简洁之处
回调函数:
回调函数就是⼀个通过函数指针调⽤的函数。如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条件发⽣时由另外的⼀⽅调⽤的,⽤于对该事件或条件进⾏响应。
回调函数
回调接⼝可能有⼀到多个⽅法需要实现,下⾯看⼀下根据不同情况的不同写法
在Kotlin中的实现⼀个接⼝通⽤写法,不管回调接⼝中有⼏个回调⽅法都可以⽤这种⽅式写
obj.addCallBack(object : CallBackInterface {
override fun aa(v:XX){
//TODO something
}
override fun bb(v:YY){
/
/TODO something
}
})
当且仅当回调接⼝只有⼀个回调⽅法的时候我们有更优雅的写法下⾯看⼀个例⼦
dataBinding.frameContainer?.tOnClickListener ({v: View ->
//todo something
})
//仅有⼀个参数并且是函数省略掉⼩括号
dataBinding.frameContainer?.tOnClickListener { it ->
//todo something
}
/
/直接省略掉it
dataBinding.frameContainer?.tOnClickListener {
//todo something
}
回调函数简单介绍这么多,下⾯看⼀下kotlin的内联扩展函数
内联函数
上⾯已经介绍了什么叫做内联函数下⾯介绍结果常⽤的内联函数的⽤法以及他们之间的区别和相似之处
内联函数之 let 和 also
*/
@kotlin.internal.InlineOnly
public inline fun <T,R>T.let(block:(T)->R):R{
contract {(this ContracBuilder)
社会实践收获callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block(this)
}
/**
* Calls the specified function [block] with `this` value as its argument and returns `this` value.
*
* For detailed usage information e the documentation for [scope functions](kotlinlang/docs/reference/scope-functions.html#also).
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T>T.also(block:(T)-> Unit):T{
contract {(this ContracBuilder)
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block(this)
return this
}
看这两个inline函数的注释可以说⼏乎是相同的,这也是为什么我要把这个两个函数放在⼀起说的原因。相同部分⼤概意思简单说⼀下“以“this”值作为参数调⽤指定函数”区别在于let函数"returns its result"意思是返回函数块的返回值 “also"函数"returns this value” 这个就直接了直接返回了”this“这就是他们的相同之处和区别
let 和 also 的简单使⽤
//在let 和 also 中it代表 obj
obj?.let {
it.tXxx(1)
it.tYyy(2)
it.addObj(obj)海商法就业前景
}
连理枝的诗句//?⽤来判空,如果obj为空直接返回空,如果不为空则执⾏函数并返回函数的执⾏结果,其实return block(this)
//的意思就是把block函数块看作⼀个整体,执⾏bolck执⾏到最后如果有返回值就返回,如果没有就是最后⼀⾏
obj?.also {
it["type1"]="1"
it["type2"]="2"
it["type3"]="3"
}
//⽤法基本相同,返回it
内联函数之 apply 和 run 上源码
*/
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.()-> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
作出贡献
}
block()
return this
}
/**
* Calls the specified function [block] with `this` value as its receiver and returns its result.
*
* For detailed usage information e the documentation for [scope functions](kotlinlang/docs/reference/scope-functions.html#run).
*/
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.()-> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
/**
* Calls the specified function [block] and returns its result.
*
* For detailed usage information e the documentation for [scope functions](kotlinlang/docs/reference/scope-functions.html#run).
*/
@kotlin.internal.InlineOnly
public inline fun <R>run(block:()-> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
你肯定已经注意到有两个run函数 这连个run函数的区别在于第⼀个⽐第⼆个多了⼀个泛型T先说这两个run函数的区别,还是看注释,以后要养成习惯看代码先看注释,看完注释⼼⾥对接下来要看的东西有个⼤概的概念,接下来才能有的放⽮。with this value as its receiver是注释当中最⼤的区别这⾥,什么意思呢,我的理解是调⽤接收对象的值,这句话就是说在函数中可以调⽤泛型T的值,⽽另⼀个run函数没有接收⽅对象,那肯定就⽆法调⽤他的值了。仅仅是执⾏block然后返回block的值。
手链的编法
接下来对⽐带泛型T的run和apply
从源码结构上看apply和run很像,他们的不同之处在于run返回block执⾏的结果,⽽apply返回的是传⼊的这个对象本⾝
apply 和 run(带泛型) run的简单使⽤
val urInfoMap = hashMapOf<Int ,String>().apply{
put(0,"1")灯盏
put(1,"2")
put(2,"3")
put(3,"4")
}
//apply 这⾥返回的是创建的这个HashMap本⾝
val rvice =MultiportService("example.kotlinlang",80)
val result = rvice.run {
// it.port = 8080
// it.query(it.prepareRequest() + " to port ${it.port}")
// 这⾥的it代表的就是是rvice
port =8080
query(prepareRequest()+" to port $port")
}
//run 返回 query(prepareRequest() + " to port $port")结果
//看着是不是有点⼉眼熟,类似于let ,只是省略掉了it,功能是完全相同的
val letResult = rvice.let{
it.port =8080
it.query(it.prepareRequest()+" to port ${it.port}")
}
//let 返回 query(prepareRequest() + " to port $port")结果
//另⼀种run不含receiver 返回赋值给变量
val hexNumberRegex = run {
val digits ="0-9"
val hexDigits ="A-Fa-f"
val sign ="+-"
Regex("[$sign]?[$digits$hexDigits]+")
}
for(match in hexNumberRegex.findAll("+1234 -FFFF not-a-number")){
println(match.value)
}
//这个⽤起来⽐较简单
内联函数之 takeIf 和 takeUnless 源码
/**
* Returns `this` value if it satisfies the given [predicate] or `null`, if it doesn't.
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T>T.takeIf(predicate:(T)-> Boolean):T?{
contract {
callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
}
return if(predicate(this))this el null
}
/**
* Returns `this` value if it _does not_ satisfy the given [predicate] or `null`, if it does.
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
我国立国之本
public inline fun <T>T.takeUnless(predicate:(T)-> Boolean):T?{
contract {
callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
}
return if(!predicate(this))this el null
}
⽼⽅法,看源码的注释 takeIf注释的⼤概意思就是条件成⽴返回对象本⾝,条件不成⽴返回空,我的理解takeIf就是⼀个变异的 if takeUnless跟takeIf相反。这两个⽅法⽤处不⼤
takeIf 和 takeUnless的简单使⽤
val number = Int(100)
val evenOrNull = number.takeIf { it %2==0}
val oddOrNull = number.takeUnless { it %2==0}
println("number: $number")
println("result: $evenOrNull, odd: $oddOrNull")
//结果
number:43
result:null, odd:43
//这两个函数需要注意的⼀个点⽤他们返回值继续操作的时候注意判空,很明显他们的返回值可能是空的
val str ="Hello"
val caps = str.takeIf { it.isNotEmpty()}?.toUpperCa()
//val caps = str.takeIf { it.isNotEmpty() }.toUpperCa() //编译通不过
println(caps)
内联函数之 with 源码
/**
* Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
迎头痛击*
* For detailed usage information e the documentation for [scope functions](kotlinlang/docs/reference/scope-functions.html#with).
*/
@kotlin.internal.InlineOnly
public inline fun <T,R>with(receiver:T, block:T.()->R):R{
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return receiver.block()
}
看注释 分为两部分,⼀个是 接收者,⼀个是函数,返回值结果是函数执⾏的结果。它不是以扩展的形式存在的。它是将某对象作为函数的参数,在函数块内可以通过 this 指代该对象。返回值为函数块
的最后⼀⾏或指定return表达式

本文发布于:2023-07-15 04:38:18,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1082029.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:函数   返回   注释   回调
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图