美文网首页Android开发经验谈Android开发Android技术知识
扣丁学堂Android培训之Kotlin内联函数分享

扣丁学堂Android培训之Kotlin内联函数分享

作者: 994d14631d16 | 来源:发表于2018-07-09 13:37 被阅读7次

      今天扣丁学堂小编给大家介绍一下关于Android培训之Kotlin内联函数分享,接下来首先来了解一下什么是内联函数呢?下面我们一起来看一下吧。

      inline函数(内联函数)从概念上讲是编译器使用函数实现的真实代码来替换每一次的函数调用,带来的最直接的好处就是节省了函数调用的开销,而缺点就是增加了所生成字节码的尺寸。基于此,在代码量不是很大的情况下,我们是否有必要将所有的函数定义为内联?让我们分两种情况进行说明:

      将普通函数定义为内联:众所周知,JVM内部已经实现了内联优化,它会在任何可以通过内联来提升性能的地方将函数调用内联化,并且相对于手动将普通函数定义为内联,通过JVM内联优化所生成的字节码,每个函数的实现只会出现一次,这样在保证减少运行时开销的同时,也没有增加字节码的尺寸;所以我们可以得出结论,对于普通函数,我们没有必要将其声明为内联函数,而是交给JVM自行优化。

      将带有lambda参数的函数定义为内联:是的,这种情况下确实可以提高性能;但在使用的过程中,我们会发现它是有诸多限制的,让我们从下面的例子开始展开说明:

      inlinefundoSomething(action:()->Unit){

      println("BeforedoSomething...")

      action()

      println("AfterdoSomething...")

      }

      假如我们这样调用doSomething:

      funmain(args:Array){

      doSomething{

      pringln("HelloWorld")

      }

      }

      上面的调用会被编译成:

      funmain(args:Array){

      println("BeforedoSomething...")

      println("HelloWorld")

      println("AfterdoSomething...")

      }

      从上面编译的结果可以看出,无论doSomething函数还是action参数都被内联了,很棒,那让我们换一种调用方式:

      funmain(args:Array){

      valaction:()->Unit={println("HelloWorld")}

      doSomething(action)

      }

      上面的调用会被编译成:

      funmain(args:Array){

      println("BeforedoSomething...")

      action()

      println("AfterdoSomething...")

      }

      doSomething函数被内联,而action参数没有被内联,这是因为以函数型变量的形式传递给doSomething的lambda在函数的调用点是不可用的,只有等到doSomething被内联后,该lambda才可以正常使用。

      通过上面的例子,我们对lambda表达式何时被内联做一下简单的总结:

      当lambda表达式以参数的形式直接传递给内联函数,那么lambda表达式的代码会被直接替换到最终生成的代码中。

      当lambda表达式在某个地方被保存起来,然后以变量形式传递给内联函数,那么此时的lambda表达式的代码将不会被内联。

      上面对lambda的内联时机进行了讨论,消化片刻后让我们再看最后一个例子:

      inlinefundoSomething(action:()->Unit,secretAction:()->Unit){

      action()

      doSomethingSecret(secretAction)

      }

      fundoSomethingSecret(secretAction:()->Unit){

      }

      上面的例子是否有问题?是的,编译器会抛出“Illegalusageofinline-parameter”的错误,这是因为Kotlin规定内联函数中的lambda参数只能被直接调用或者传递给另外一个内联函数,除此之外不能作为他用;那我们如果确实想要将某一个lambda传递给一个非内联函数怎么办?我们只需将上述代码这样改造即可:

      inlinefundoSomething(action:()->Unit,noinlinesecretAction:()->Unit){

      action()

      doSomethingSecret(secretAction)

      }

      fundoSomethingSecret(secretAction:()->Unit){

      }

      很简单,在不需要内联的lambda参数前加上noinline修饰符就可以了。

      以上便是我对内联函数的全部理解,通过掌握该特性的运行机制,相信大家可以做到在正确的时机使用该特性,而非滥用或因恐惧弃而不用。

      以上就是关于扣丁学堂Android培训之Kotlin内联函数的详细技术,希望本文的内容对学习Android开发费有深入的了解,如果你想学习更多的Android知识,对Android有全面的了解,请关注扣丁学堂微信公众号,或登录扣丁学堂官网了解更多,还有大量Android视频教程等着你来观看。

    相关文章

      网友评论

        本文标题:扣丁学堂Android培训之Kotlin内联函数分享

        本文链接:https://www.haomeiwen.com/subject/zwnzuftx.html