1. 高介函数
在 Kotlin 中,高阶函数是指将函数作为参数或者返回值的函数。
- 格式:(参数)-> return_type
1.1 定义函数类型
通过关键 typealias 声明一个 函数类型,在其他函数的入参中可以直接使用
//定义了FuncType 这样一个函数类型
typealias FuncType = (Int) -> Int
//processFunction 函数接受 FunType 类型的参数
fun processFunction(func: FuncType) {
// 在这里可以使用传递进来的函数 func
println(func(3))
}
//processFunction 函数接受 FunType 类型的参数
inline fun inlineProcessFunction(func: FuncType) {
// 在这里可以使用传递进来的函数 func
println(func(3))
}
1.2 将函数作为入参
以下是一个将函数作为参数的高阶函数示例
//高阶函数:函数作为入参
fun calculate(num1: Int, num2: Int, operation: (Int, Int) -> Int): Int {
return operation(num1, num2)
}
//普通函数
fun add(num1: Int, num2: Int): Int {
return num1 + num2
}
fun main() {
//第一种:定义一个 add() 函数,将add函数作为参数,传入到 calculate()中
//::add 是函数引用的一种写法。
//使用 ::引入add函数,将add 函数作为第三个参数传入到calculate()中
var sum = calculate(2, 3, ::add)
//第二种:通过 lambda 表达式的方式,作为第三个参数
var sum2 = calculate(2, 3) { n1, n2 ->
n1 + n2
}
println("sum = $sum")
println("sum2 = $sum2")
//定义个无参的 高阶函数 calculate2()
//通过 lambda 表达式的方式,作为第三个参数, lambda 表达式为无参
var sum3 = calculate2(2,3){
println("执行 calculate2")
}
println("sum3 = $sum3")
}
//lambda 表达式不需要参数
fun calculate2(num2: Int, num1: Int, print: () -> Unit): Int {
//执行函数
print()
return add(num1, num2)
}
// 执行结果
//sum = 5
//sum2 = 5
//执行 calculate2
//sum3 = 5 -->
2. 将函数作为返回值
在这个示例中,createOperation 函数根据传入的字符串返回不同的函数。
//普通函数
fun add(num1: Int, num2: Int): Int {
return num1 + num2
}
//普通函数
fun multiply(num1: Int, num2: Int): Int {
return num1 * num2
}
//将函数作为返回值
fun createOperation(operationType: String): (Int, Int) -> Int {
return when (operationType) {
"add" -> ::add
"multiply" -> ::multiply
else -> { _, _ -> 0 }
}
}
fun main() {
//定义高阶函数:返回值为函数
val addOperation = createOperation("add")
val multiplyOperation = createOperation("multiply")
val multiplyOperation2 = createOperation("multiply2")
val sum4 = addOperation(5, 3)
val product = multiplyOperation(5, 3)
val product2 = multiplyOperation2(5, 3)
println("sum4: $sum4")
println("Product: $product")
println("Product2: $product2")
}
//输出结果
//sum4: 8
//Product: 15
//Product2: 0
3. 函数入参定义为扩展函数
在函数类型的前面加上 className. 表示将函数定义在某个类中即类的扩展函数,使lambda表达式中持有该类的上下文:如 StringBuilder.() 类似 apply 函数
//在函数类型的前面加上 className. 表示将函数定义在某个类中即类的扩展函数,
// 使lambda表达式中持有该类的上下文:如 StringBuilder.()
fun StringBuilder.build(block: StringBuilder.()->Unit):StringBuilder{
block()
return this
}
//定义一个扩展函数,用于对String进行操作
fun String.toUpperCaseWithExclamation(): String = this.toUpperCase() + "!"
//定义一个顶层函数使其接受 String扩展函数 ,并返回扩展函数应用后的结果
fun test(block: String.() -> String): String {
// 假设我们有一个String实例
val str = "hello"
// 调用传入的扩展函数,并将str作为接收者
return str.block()
}
fun main() {
//高阶函数:入参函数作为某个类的扩展函数如:StringBuilder.()
var list = listOf("Apple","Orange","Pear","Grape")
var sb= StringBuilder()
sb.build {
append("高阶函数,StringBuilder.() 在lambda 主体中默认持有 StringBuilder 的上下文")
list.forEach {
append(" $it ,")
}
}
println("sb 内容 = ${sb.toString()}")
//使用顶层方法 入参String的扩展函数,lambda 表达式中默认持有String 的引用,所以可以直接调用 String 的扩展函数
var ss = test {
toUpperCaseWithExclamation()
}
println("ss 内容 = ${ss.toString()}")
}
//打印结果
sb 内容 = 高阶函数,StringBuilder.() 在lambda 主体中默认持有 StringBuilder 的上下文 Apple , Orange , Pear , Grape ,
length = 5
ss 内容 = HELLO!