08-高阶函数基本用法
11.2.1 高阶函数基本用法
高阶函数(Higher Order Function)是一种特殊的函数,它接收函数作为参数,或者返回一个函数。函数的基本格式如下。
fun 高阶函数名(参数函数名:参数函数类型):高阶函数返回类型{
//高阶函数体
}
高阶函数的一个很好的例子就是lock函数,它的参数是一个Lock类型对象和一个函数。该函数执行时获取锁,运行函数参数,运行结束后再释放锁。
fun <T> lock(lock: Lock, body: () -> T): T {
lock.lock()
try {
return body()
}finally {
lock.unlock()
}
}
在上面的代码中,body为函数的类型对象,该函数是一个无参函数,而且返回值类型为T。
调用lock函数时,可以传入另一个函数作为参数。和许多编程语言类似,如果函数的最后一个参数也是函数,则该函数参数还可以定义在括号外面。代码如下。
val result = lock(lock, { sharedResource.operation() })
//等同于
lock (lock) {
sharedResource.operation()
}
高阶函数可以接收函数作为参数,也可以返回一个函数的引用,并将此函数赋值给一个变量。
fun bar(): (String) -> String = { str -> str.reversed() }
fun main(args: Array<String>) {
val rever = bar()
rever("hello world")
}
高阶函数类似C语言的函数指针,它的另一个使用场景是map函数。如果函数只有一个参数,则可以忽略声明的函数参数,用it来代替。
fun <T, R> List<T>.map(transform: (T) -> R): List<R> {
val result = arrayListOf<R>()
for (item in this)
result.add(transform(item))
return result
}
//调用map函数
val doubled = ints.map { it -> it * 2 }
如果Lambda表达式的参数未使用,则可以使用下划线来替代该参数。
map.forEach { _, value -> println("$value!") }
使用高阶函数时,应注意以下几点。
- 包级函数作为高阶函数的参数时,可以通过参数、返回值来判断该函数是否合适。
- 使用类的成员函数(带有Receiver的函数)作为高阶函数的参数时,需要使用类的实例来进行引用。
- 扩展方法作为高阶函数的参数时,有一个默认的参数就是实例本身。