Kotlin 高阶函数与内联函数

1、前言

<font face= 黑体>在 Kotlin 学习笔记以内置类型(2)中咱们已经将 Kotlin 函数的基本概念基本用法讲完了,今天咱们来说函数进阶java

2、高阶函数

2.一、高阶函数概念

<font face= 黑体>高阶函数就是参数类型包含函数类型或者返回值类型是函数类型的函数,简单的说,高阶函数就是函数里面套函数,以下所示:git

// 参数类型是函数类型
fun needsFunction(block: () -> Unit) {
    block()
}

// 返回值是函数类型
fun returnsFunction(): () -> Long {
    return {System.currentTimeMillis()}
}

2.二、常见的高阶函数

  1. <font face= 黑体>forEach 函数: 接受的参数是一个函数github

    // Kotin 自带的 forEach 函数
    inline fun IntArray.forEach(action: (Int) -> Unit): Unit {
        for (element in this) action(element)
    }
  2. <font face= 黑体>map 函数: 接受的参数是一个函数segmentfault

    // Kotin 自带的 map 函数
    inline fun <R> IntArray.map(transform: (Int) -> R): List<R> {
        return mapTo(ArrayList<R>(size), transform)
    }

2.三、高阶函数的调用

<font face= 黑体>forEach 的调用:数组

val intArray = IntArray(5){ it + 1 }

intArray.forEach(::println)

// 括号() 里面其实能够把它当作一个参数,只是这个参数是函数
intArray.forEach ({
    println(it)
})

// () 能够省略,就变成了下面这样
intArray.forEach {
    println(it)
}
<font face= 黑体>forEach 接受的类型参数类型是 (Int) -> Unit,而 println 函数的类型有一个就是 (Int) -> Unit,因此能够用函数引用来接收。

3、内联函数

3.一、内联函数概念

<font face= 黑体>被 inline 标记的函数就是内联函数,其原理就是:在编译时期,把调用这个函数的地方用这个函数的方法体进行替换。咱们来看下面这个代码,就是一个 forEach 函数遍历数组:性能优化

val ints = intArrayOf(1, 2, 3, 4)
ints.forEach {
    println("Hello $it")
}

<font face= 黑体>forEach 函数的定义上面咱们已经看到了,以下,能够看到,forEach 被 inline 修饰,因此它是个内联函数函数

inline fun IntArray.forEach(action: (Int) -> Unit): Unit {
    for (element in this) action(element)
}

<font face= 黑体>其实 forEach 真正的实现是下面这个代码:性能

for (element in this) action(element)

<font face= 黑体>内联函数能够减小函数的调用来优化性能。学习

3.二、内联函数的定义

<font face= 黑体>内联函数的定义很简单,就是在一个函数的前面加上 inline 关键字。优化

inline fun hello() {
    println("hello")
}

<font face= 黑体>虽说内联函数能够减小函数的调用来优化性能,可是并非每一个函数前加一个 inline 就能够优化性能,其实咱们通常会把高阶函数定义为内联函数。

3.三、高阶函数与内联函数更配

cost {
    println("hello")
}
inline fun cost(block: () -> Unit) {
    val start = System.currentTimeMillis()
    block()
    println(System.currentTimeMillis() - start)
}

<font face= 黑体>好比说咱们要计算 println("hello") 这段代码执行的时间,若是不加 inline 的话,那么调用 cost 就要建立 Lambda 表达式,函数调用,结果发现这些操做的时间就要大于 println("hello") 这段代码执行的时间,这样是彻底没有必要的,因此咱们加上 inline 以后,调用 println("hello"),实际上就等于下面这样:

val start = System.currentTimeMillis()
println("hello")
println(System.currentTimeMillis() - start)
<font face= 黑体>能够看到加上 inline 以后,cost 函数的调用开销没了,Lambda 表达式的建立开销也没了,这就是内联函数的做用。

3.四、内联函数的限制

  • <font face= 黑体>public/protected 的内联方法只能访问对应类的 public 成员;
  • <font face= 黑体>内联函数里面的参数不能被存储(赋值给一个变量);
  • <font face= 黑体>内联函数的参数只能传递给其余内联函数。
<font face= 黑体> 其实内联函数最重要的是对高阶函数的性能优化。

4、小结

<font face= 黑体>本篇博客主要讲了 Kotlin 中的高阶函数内联函数,下一节咱们讲 Kotin 的 集合变换与聚合

5、源码

源码 已上传至 github,有须要能够直接下载。

相关文章
相关标签/搜索