啥是高阶函数
高阶函数是一个函数,他的参数是另一个函数。
函数作为返回类型
val sum: (Int, Int) -> Int = { x, y -> x + y }
val action: () -> Unit = { println(42) }
val canReturnNull: (Int, Int) -> Int? = { null }
val funOrNull: ((Int, Int) -> Int)? = null
函数作为参数
fun twoAndThree(operator: (Int, Int) -> Int){
val result = operator(2,3)
println(result)
}
inline函数
使用高阶函数(higher-order functions)会导致一些性能的损耗:
每个函数都是对象,且会捕获闭包closure(即变量会在函数体内被访问),
函数对象/类会增加内存分配,而且虚拟调用栈也会增加额外内存开销!
可用内联函数(inline function)消除这些额外内存开销,
说白了就是在调用处插入函数体代码,以此减少新建函数栈和对象的内存开销!
被inline修饰的函数或lambda表达式,在调用时都会被内联(在调用处插入函数体代码)
inline fun synchronized<T>(lock: Lock, body: () -> T): T {
lock.lock()
try {
return body()
}
finally {
lock.unlock()
}
}
print("开始************")
synchronized(l) { foo() }
print("结束************")
//编译器实际生成以下代码(就是直接把代码插入到调用处):
print("开始************")
l.lock()
try {
foo()
}
finally {
l.unlock()
}
print("结束************")
很明显,内联可能导致编译器生成的代码增加,但如果使用得当(不内联大函数),在性能上有很大提升,尤其是在循环的megamorphic处调用!
禁用内联(noinline)
如果内联函数的有些(作为参数)lambda表达式不是内联,可用noinline修饰符函数参数!
inline fun foo(inlined: () -> Unit, noinline notInlined: () -> Unit) {
// ……
}
从Lambda返回
fun lookForAlice(people: List<Person>{
people.foreach label@{
if (it.name == "Alice") return@label
}
}
fun lookForAlice(people: List<Person>{
people.foreach {
if (it.name == "Alice") return@forEach
}
}
看一下标签的别的用法
StringBuilder().apply sb@{
listOf(1,2,3,4).apply{
this@sb.append(this.toString())
}
}
匿名函数
fun lookForAlice(l: List<Int>){
l.forEach(fun (i){
if (i == 1) return;//从匿名函数返回
})
}
val oneFun = fun(i){ //.. }