- 定义:一个函数以另一个函数作为参数,或返回值的类型是另一个函数。
(String, Int) -> Unit
fun example(func: (String, Int) -> Unit) {
func("hello", 123)
}
// 这里Unit相当于Java中的void
fun num1AndNum2(num1: Int, num2: Int, operation: (Int, Int) -> Int): Int {
return operation(num1, num2)
}
fun plus(n1: Int, n2: Int) = n1 + n2
fun minus(n1: Int, n2: Int) = n1 - n2
fun main() {
val num1 = 90
val num2 = 80
println(num1AndNum2(num1, num2, ::plus))
println(num1AndNum2(num1, num2, ::minus))
println(num1AndNum2(num1, num2) { n1: Int, n2: Int ->
n1 * n2
})
}
- 小知识:当内部变量和外部变量重名,导致nameshadowed
- 给函数参数lambda表达式提供上下文
fun main() {
val list = listOf<String>("apple", "banana", "orange", "grape")
val result = StringBuilder().fruitBuild {
append("start eating fruits.\n")
for (fruit in list) {
append(fruit)
append("\n")
}
append("ate all fruits")
}
println(result)
}
// StringBuilder.()表明函数定义在该类中,拥有该类的上下文
fun StringBuilder.fruitBuild(block: StringBuilder.() -> Unit): StringBuilder {
block()
return this
}
- 内联函数:如果没有inline关键字,则每次调用上面高阶函数的lambda表达式,都会创建一个新的匿名类实例,(调用的时候使用.invoke()函数),造成带来运行时的额外的内存和性能开销。
- 指定内联函数
inline fun inlineTest(block1: () -> Unit, noinline block2: () -> Unit) {
}
- 指定noinline,区别在于
- 内联的函数类型参数在编译的时候会被代码替换,因此没有正真的参数属性。对比非内敛的函数类型参数,可以传递给其他参数。
- 内敛函数引用的lambda表达式可以使用return关键字进行函数返回,非内联函数只能进行局部返回。
- 指定crossinline: 约定不会在内联函数的lambda表达式中使用return关键字。因为内联函数可以进行外层函数的返回,而lambda不行,因此在lambda中调用内联函数就会出现冲突。通过指定crossinline约定避免这个问题。
inline fun runRunnable(crossinline block: () -> Unit) {
val runnable = Runnable {
block()
}
}