Kotlin研发第十四弹——内联函数

26 篇文章 0 订阅
25 篇文章 0 订阅

内联函数

1、内联函数

使用高阶函数带来了响应的运行时麻烦:**每个函数都是一个对象,它捕获闭包,即这些变量可以在函数体内被访问,减少了内存:**毕竟内存的分配,虚拟调用的运行都会带来开销

但是大多数开销都可以用**内联函数inline**避免

内联函数具体的在之前讲到了,这边就不细讲,就单纯的写两个例子

//内联函数
inline fun <T> addStringTest(test1:T,inlined:(T,T)->T):T {
    return inlined(test1,test1)
}
infix fun String.addString(s:String):String=this+s

println(addStringTest("zhe shi inline fun") { s1, s2 ->s1 addString s2 })

输出结果

zhe shi inline funzhe shi inline fun

2、非内联函数

前面有说这里也就给个例子

//非内联函数
inline fun <T> addStringNoLine(test1: T,inlined: (T, T) -> T,noinline noinlined:(t:T)->T ):T{
    return test1 sum inlined(noinlined(test1),test1)
}
infix fun <T> T.sum(t:T):T{
    return t 
}
println(addStringNoLine("this is boy",{t1,t2->"$t1+$t2"}){it.toUpperCase()})

输出结果

THIS IS BOY+this is boy
返回到非局部

在kotlin中,我们可以不加条件的使用return去推出一个命名函数或表达式函数。这意味着推出一个lambda函数,我们不得不使用标签,而且空白的return在lambda函数中是禁止,因为lambda函数不可以造一个闭合函数返回:

返回到非局部 ??

在kotlin中,我们可以不加条件的使用return去退出一个明明函数或者表达式函数。这意味着退出一个lambda函数,我们不得不使用标签,而且空白的return在lambda函数中是禁止的,因为lambda函数不可以在一个闭合函数中返回

错误事例

//返回到非局部的错误事例
fun testLocalError(){
    labdTest{
        return //错误,在lambda函数中不可以在闭合函数中返回
    }
}

fun labdTest(test:()->Int){
    test()
}

正确做法应该是返回

//返回到非局部的错误事例
fun testLocalError(){
    labdTest{
        return@labdTest //错误,在lambda函数中不可以在闭合函数中返回
    }
}

fun labdTest(test: () -> Unit){
    test()
}

注意:lambda如果是内联传递的,则返回也是内联传递的,因此允许下面这样:

//返回到非局部
fun testLocal(){
    inlineTest("ceshi"){
        return
    }
}
//内联函数
inline fun inlineTest(prefix: String, action: () -> Unit) {
    println("call before $prefix")
    action()
    println("call after $prefix")
}

输出结果

call before ceshi
注意有些内联函数可以调用传递进来的lambda函数,但不是在函数体,而是在另一个执行的上下文中。需要有crossinline注解才能???

crossinline:不允许非局部返回,强制设置为全局返回

一些内联函数可能调用传给它们的不是直接来自函数体、而是来自另一个执行上下文的 lambda 表达式参数,例如来自局部对象或嵌套函数。在这种情况下,该 lambda 表达式中也不允许非局部控制流。为了标识这种情况,该 lambda 表达式参数需要用 crossinline 修饰符标记。
//这个无法复现不知道具体原因,下方的代码能够实现
inline fun f(inlineOptions(InlineOption.ONLY_LOCAL_RETURN) body: () -> Unit) {
    val f = object: Runnable {
        override fun run() = body()
    }


inline fun f(crossinline body: () -> Unit) {
    val f = object : Runnable {
        override fun run() = body()
    }
}

实例化参数类型

在讲实例化参数类型之前我们必须明确一个修饰词的含义reified

reified 是什么

**reified?*具体化,可以理解成具体化一个东西

//reified 实例化
inline fun <reified T> membersOf() = T::class.members

//测试reified实例化
// println(membersOf<Int>().joinToString { "\n" })
println(membersOf<StringBuilder>())

输出的话就是实例的对象内容

[fun java.lang.StringBuilder.insert(kotlin.Int, kotlin.CharArray!, kotlin.Int, kotlin.Int): java.lang.StringBuilder!, fun java.lang.StringBuilder.insert(kotlin.Int, kotlin.Double): java.lang.StringBuilder!, fun java.lang.StringBuilder.insert(kotlin.Int, kotlin.Float): java.lang.StringBuilder!, fun java.lang.StringBuilder.insert(kotlin.Int, kotlin.Long): java.lang.StringBuilder!, fun java.lang.StringBuilder.insert(kotlin.Int, kotlin.Int): java.lang.StringBuilder!, fun java.lang.StringBuilder.insert(kotlin.Int, kotlin.Any!): java.lang.StringBuilder!, fun java.lang.StringBuilder.insert(kotlin.Int, kotlin.String!): java.lang.StringBuilder!, fun java.lang.StringBuilder.insert(kotlin.Int, kotlin.CharArray!): java.lang.StringBuilder!, fun java.lang.StringBuilder.insert(kotlin.Int, kotlin.CharSequence!): java.lang.StringBuilder!, fun java.lang.StringBuilder.insert(kotlin.Int, kotlin.CharSequence!, kotlin.Int, kotlin.Int): java.lang.StringBuilder!, fun java.lang.StringBuilder.insert(kotlin.Int, kotlin.Boolean): java.lang.StringBuilder!, fun java.lang.StringBuilder.insert(kotlin.Int, kotlin.Char): java.lang.StringBuilder!, fun java.lang.StringBuilder.append(kotlin.Boolean): java.lang.StringBuilder!, fun java.lang.StringBuilder.append(kotlin.CharSequence!): java.lang.StringBuilder!, fun java.lang.StringBuilder.append(kotlin.Char): java.lang.StringBuilder!, fun java.lang.StringBuilder.append(kotlin.Int): java.lang.StringBuilder!, fun java.lang.StringBuilder.append(java.lang.StringBuffer!): java.lang.StringBuilder!, fun java.lang.StringBuilder.append(kotlin.CharArray!): java.lang.StringBuilder!, fun java.lang.StringBuilder.append(kotlin.CharSequence!, kotlin.Int, kotlin.Int): java.lang.StringBuilder!, fun java.lang.StringBuilder.append(kotlin.Double): java.lang.StringBuilder!, fun java.lang.StringBuilder.append(kotlin.CharArray!, kotlin.Int, kotlin.Int): java.lang.StringBuilder!, fun java.lang.StringBuilder.append(kotlin.String!): java.lang.StringBuilder!, fun java.lang.StringBuilder.append(kotlin.Any!): java.lang.StringBuilder!, fun java.lang.StringBuilder.append(kotlin.Long): java.lang.StringBuilder!, fun java.lang.StringBuilder.append(kotlin.Float): java.lang.StringBuilder!, fun java.lang.StringBuilder.deleteCharAt(kotlin.Int): java.lang.StringBuilder!, fun java.lang.StringBuilder.replace(kotlin.Int, kotlin.Int, kotlin.String!): java.lang.StringBuilder!, fun java.lang.StringBuilder.appendCodePoint(kotlin.Int): java.lang.StringBuilder!, fun java.lang.StringBuilder.delete(kotlin.Int, kotlin.Int): java.lang.StringBuilder!, fun java.lang.StringBuilder.reverse(): java.lang.StringBuilder!, fun java.lang.StringBuilder.indexOf(kotlin.String!, kotlin.Int): kotlin.Int, fun java.lang.StringBuilder.indexOf(kotlin.String!): kotlin.Int, fun java.lang.StringBuilder.lastIndexOf(kotlin.String!, kotlin.Int): kotlin.Int, fun java.lang.StringBuilder.lastIndexOf(kotlin.String!): kotlin.Int, fun java.lang.StringBuilder.toString(): kotlin.String, fun java.lang.StringBuilder.readObject(java.io.ObjectInputStream!): kotlin.Unit, fun java.lang.StringBuilder.writeObject(java.io.ObjectOutputStream!): kotlin.Unit, fun java.lang.StringBuilder.substring(kotlin.Int, kotlin.Int): kotlin.String!, fun java.lang.StringBuilder.substring(kotlin.Int): kotlin.String!, fun java.lang.StringBuilder.offsetByCodePoints(kotlin.Int, kotlin.Int): kotlin.Int, fun java.lang.StringBuilder.append(java.lang.AbstractStringBuilder!): java.lang.AbstractStringBuilder!, fun java.lang.StringBuilder.chars(): java.util.stream.IntStream!, fun java.lang.StringBuilder.getChars(kotlin.Int, kotlin.Int, kotlin.CharArray!, kotlin.Int): kotlin.Unit, fun java.lang.StringBuilder.getValue(): kotlin.CharArray!, fun java.lang.StringBuilder.get(kotlin.Int): kotlin.Char, fun java.lang.StringBuilder.codePointBefore(kotlin.Int): kotlin.Int, fun java.lang.StringBuilder.trimToSize(): kotlin.Unit, fun java.lang.StringBuilder.hashCode(): kotlin.Int, fun java.lang.StringBuilder.codePoints(): java.util.stream.IntStream!, fun java.lang.StringBuilder.codePointAt(kotlin.Int): kotlin.Int, fun java.lang.StringBuilder.equals(kotlin.Any?): kotlin.Boolean, fun java.lang.StringBuilder.capacity(): kotlin.Int, fun java.lang.StringBuilder.setLength(kotlin.Int): kotlin.Unit, fun java.lang.StringBuilder.codePointCount(kotlin.Int, kotlin.Int): kotlin.Int, fun java.lang.StringBuilder.ensureCapacity(kotlin.Int): kotlin.Unit, fun java.lang.StringBuilder.setCharAt(kotlin.Int, kotlin.Char): kotlin.Unit, fun java.lang.StringBuilder.subSequence(kotlin.Int, kotlin.Int): kotlin.CharSequence, var java.lang.StringBuilder.value: kotlin.CharArray!, var java.lang.StringBuilder.count: kotlin.Int, val java.lang.StringBuilder.length: kotlin.Int, val serialVersionUID: kotlin.Long]

内联函数支持类型参数,并且需要类型实例化,所以和 reified何用能实例

我们用reified修饰符检查类型参数,因为函数是内联的,所以不虚反射,像!is as这样的操作都可以使用

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值