【Kotlin】inline,noinline,crossinline

inline

inline修饰函数,表示內联函数,对函数进行优化,调用对函数在编译时变成代码内嵌对形式,相当于把函数体展开,平铺到调用处。这样的好处时减少了函数的调用栈,但是这种好处小到可以忽略不计,甚至如果函数体过大,并且调用函数有很多此,就会导致每个调用函数的地方都平铺函数体,造成字节码体积过大,形成负优化。

inline fun f1(){//这种优化并没有什么用,android studio都出现警告了
    println("inline")
}

内联最适用于具有函数类型参数的函数,因为kotlin的函数类型在jvm编译时会是一个对象,使用inline修饰时可以减少对象的创建

inline fun i1(callback:()->Unit){
    println("hello")
    callback.invoke()
}

fun main() {
    i1{
		println("inline")
    }
}
//相当于
fun main(){
	println("hello")
	println("inline")
}

在inline修饰的函数中,并且函数参数是函数类型,在调用函数时,可以在lambda中写return,表示的是返回此函数的外层函数。lambda表达式中不能使用return,除非这个了lambda是內联函数的参数

inline fun i1(callback:()->Unit){
    println("hello")
    callback.invoke()
}

fun main() {
    i1{
        println("inline")
        return
    }
}
//相当于
fun main() {
  	println("hello")
	println("inline")
	return
}

noinline

noinline用来修饰函数类型参数,可以对一个或多个函数类型参数取消內联优化。因为函数类型实质上是一个对象,如果这个对象不需要被使用,使用inline没问题,一旦需要用到这个对象时,就不能使用inline了,inline的本质是将函数平铺到调用方,内部的函数类型的参数不再是对象了。

inline fun i2( pre:(String)->Int, after:(Int)->String){
    pre("ll")
    println("hello")
    val a = after//对象赋值,用到对象,这时会报错,必须把这个参数用noline修饰
}


inline fun i2( pre:(String)->Int,noinline after:(Int)->String){
    pre("ll")
    println("hello")
    val a = after
}

用来局部的关闭优化,因为这种优化会导致函数中的函数类型的参数无法被当做对象使用。

crossinline

crossinline也是修饰函数类型参数,是加强inline內联优化,可以间接调用函数类型的参数。
內联函数不允许函数类型参数被间接调用

inline fun f1(block:()->Unit){
    f2{
        block.invoke()//在f2中调用函数类型,间接调用,是不被允许的,报错
    }
}

fun f2(block: () -> Unit){
    
}

解决上面问题的办法是在函数类型的参数用crossinline进行修饰

inline fun f1(crossinline block:()->Unit){
    f2{
        block.invoke()
    }
}

fun f2(block: () -> Unit){

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值