一、高阶函数的定义
高阶函数是一种特殊的函数,能够接收一个或多个函数作为参数,并且/或者返回一个函数的函数,这意味着在Kotlin中,函数可以像其他数据类型(如整数、字符串等)一样被传递和操作。 高阶函数的存在使得函数可以成为更灵活和可复用的代码单元。它们可以用来抽象通用的操作或行为,并将其作为参数传递给其他函数,从而使代码更加简洁和可维护。
二、高阶函数的用法
1.函数类型
这里定义的参数test为参数为Int,返回值为Int的函数类型
/*
变量test为函数类型
test方法中参数为Int,返回值为Unit
*/
val test:(Int)->Unit
2.函数的引用方法
在拥有一个已经定义好的函数show后,可以通过使用::来对函数进行引用,可以将其赋值给变量center,此时center也为参数为空,返回值为Unit的函数类型。
fun show(){
println("show")
}
val center:()->Unit = ::show
3.Lambda表达式
定义
Lambda表达式是一种轻量级的语法形式,用于表示一个匿名函数。它可以在需要函数作为参数的地方传递代码块,并且可以访问其周围的变量。
Lambda表达式的语法形式为:{ 参数列表 -> 函数体 }。其中,参数列表可以是零个或多个参数,函数体可以是一个表达式或一段代码块。
用法
当一个函数的参数为函数类型时,可以传递一个Lambda表达式作为参数。在函数内部,可以调用Lambda表达式来执行特定的操作。
1.先定义一个高阶函数,其中有一个函数类型的task参数,且为doSomething()的最后一个参数。在其内部,也调用了整型参数money和函数类型参数task()。
/*
这里定义了一个高阶函数doSomething
*/
fun doSomething(money:Int,task:()->Unit){
println("get money $money")
task()
}
2.在调用函数doSomething时,可以触发lambda表达式,Lambda表达式的主体部分位于{}
内部,本次例子中,{}内部是task:()->Unit的具体实现。在doSomething()方法被调用后,运行过程中
先执行 println("get money $money") 再执行 task()
运行结果:
get money 40 show
//1. 原始的模样
doSomething(30,{
println("show")
})
//2. lambda表达式
doSomething(40){
println("show")
}
3.当函数参数中有两个参数的情况:
/*
参数callBack中,有两个参数
*/
fun doOtherThing(a:Int,b:Int,callBack: (Int,Int) -> Unit){
callBack(a,b)
}
//调用doOtherThing,num1,num2为参数函数的参数
doOtherThing(3,4){ num1,num2 ->
}
4.高阶函数的应用
网络请求是高阶函数的常用地方之一,这里也以网络请求来举例高阶函数的应用。
inner class NetWork(){
//第一步 发起网络请求 高阶函数形式
fun requestWithLambda(block:(String)-> Unit){
Log.v("Target","发起网络请求")
for (i in 1..5){
Log.v("Target","网络请求中...")
}
Log.v("Target","网络请求成功!")
//TODO() 将结果返回给MainActivity
block("返回的数据:....")
}
}
private var target = ""
//第二步 使用
val netWork = NetWork()
netWork.requestWithLambda {
target = it
Log.v("Target","通过高阶函数的形式得到了数据")
}
5.内联函数inline
内联函数(inline function)与其他编程语言的内联函数概念相似,它可以在函数调用处直接将函数体插入,从而避免了函数调用的开销。
使用关键字inline
进行声明。通过将函数标记为内联,编译器会将函数体直接插入到调用处,而不是进行函数调用。实例如下:
inline fun calculateSum(a: Int, b: Int): Int {
return a + b
}
fun main() {
val sum = calculateSum(3, 5)
println("Sum: $sum")
}
三、自己写一个forEach函数
/*
自己写一个forEach方法
*/
fun Array<Int>.myIntForEach(a:(Int)->Unit){
for (i in this){
a(i)
}
}
/*
调用我的myIntForEach方法
*/
val nums = arrayOf(1,2,3)
nums.myIntForEach {
}
也可以将Int类型变为泛型
fun<T> Array<T>.myForEach(a:(T)->Unit){
for (i in this){
a(i)
}
}