高阶函数是指将函数作为参数或者返回值的函数。
在 Kotlin 中,每个函数都有特定的类型,函数类型由 函数的形参列表
+ ->
+ 返回值类型
组成,例如:
fun getName(id:String):String{
}
上面这个 getName
函数的函数类型就是 (String) -> String
。
如果是没有返回值的函数:
fun setName(name: String){
}
上面的函数的函数类型就是:(String)->Unit
或者也可以简写为 (String)
如果是无参的函数:
fun getName():String{
}
上面的函数的函数类型就是 ()->String
在 Kotlin 中,函数类型既可以作为变量,也可以作为形参还可以作为返回值类型来使用。
定义一个变量,其类型为函数类型:
var test : (String) ->String
这样一个变量定义完成之后,然后我们开始使用这个变量:
fun main() {
var test: (String) -> String
test = ::getName
println(test("ccccc"))
//下面就会报错,因为函数类型不同
// test = ::getNameList
//修改一下函数类型,就可以了
var test1: () -> MutableList<String>
test1 = ::getNameList
}
fun getName(id: String): String {
when (id) {
"aaaaa" -> return "张三"
"bbbbb" -> return "李四"
else -> return "王五"
}
}
fun getNameList(): MutableList<String> {
return mutableListOf<String>("张三", "李四", "王五")
}
上面说过了,函数类型可以作为形参传入,我们可以将函数类型作为形参传入到方法中,又因为不同的方法可能形参相同,那么就可以在一个方法中去调用不同的方法了,一个简单的例子:
fun main() {
var sum = mathOperation(1, 2, ::sum)
println("加法: $sum")
var sub = mathOperation(1, 2, ::sub)
println("减法: $sub")
var mult = mathOperation(1, 2, ::mult)
println("乘法: $mult")
var div = mathOperation(1, 2, ::div)
println("除法: $div")
}
/**
* compute 就是一个函数类型,作为参数,在方法体内可以直接调用相关方法
*/
fun mathOperation(a: Int, b: Int, compute: (Int, Int) -> Int): Int {
return compute(a, b)
}
fun sum(a: Int, b: Int): Int {
return a + b
}
fun sub(a: Int, b: Int): Int {
return if (a >= b) {
a - b
} else {
b - a
}
}
fun mult(a: Int, b: Int): Int {
return a * b
}
fun div(a: Int, b: Int): Int {
return if (a >= b) {
a - b
} else {
b - a
}
}
输出结果:
加法: 3
减法: 1
乘法: 2
除法: 1
将参数类型作为返回值,然后返回值可以作为方法直接使用:
fun main() {
var matchFunc = getMathFunc("cube")
println(matchFunc(5))
matchFunc = getMathFunc("square")
println(matchFunc(5))
matchFunc = getMathFunc("other")
println(matchFunc(5))
}
fun getMathFunc(type: String): (Int) -> Int {
//定义一个计算平法的局部函数
fun square(n: Int): Int {
return n * n
}
//定义一个计算立方的局部函数
fun cube(n: Int): Int {
return n * n * n
}
//定义一个计算阶乘的局部函数
fun factorial(n: Int): Int {
var result = 1
for (index in 2..n) {
result *= index
}
return result
}
return when (type) {
"square" -> ::square
"cube" -> ::cube
else -> ::factorial
}
}
//示例代码来自《疯狂 Kotlin 讲义》
//执行结果:
125
25
120
Lambda 本质是一种匿名函数,作为表达式,它的运行结果可以作为表达式、形参和函数返回值。
Lambda 表达式的格式大致为:
{
参数->Lambda体
}
在上一个例子中,when 表达式的每个分支都又另外调去了一个局部方法,每个方法(方法体中)都有不同的计算形式,既然函数可以作为返回值,那么上面那个例子就可以修改为
fun main() {
var matchFunc = getMathFunc("cube")
println(matchFunc(5))
matchFunc = getMathFunc("square")
println(matchFunc(5))
matchFunc = getMathFunc("other")
println(matchFunc(5))
}
fun getMathFunc(type: String): (Int) -> Int {
return when (type) {
"square" -> return { n: Int -> n * n }
"cube" -> return { n: Int -> n * n * n }
else -> return { n: Int ->
var result = 1
for (index in 2..n) {
result *= index
}
result
}
}
}
//执行结果是一样的
其实不难发现,上面那个例子,实际上就是将整个函数作为返回值,《疯狂 Kotlin 讲义》中总结了 Lambda 的几个特点:
->
前面,参数类型可以省略->
后面