kotlin高阶函数(1)——将函数作为参数传递
问题背景
kotlin语言中,有个高阶函数的概念,那么什么是高阶函数呢? 高阶函数的定义:一个函数如果参数类型是函数或者返回值类型是函数,那么这就是一个高阶函数。 现在我们来看第一个:Kotlin 支持函数作为参数传递,无需构建对象来包装函数。
问题分析
(1)函数类型
kotlin 中,有整型 Int、字符串类型 String,同样函数也有类型,举个例子:
fun add(num1: Int, num2: Int): Int {
return num1 + num2
}
这个 add 函数的函数类型就是 (Int, Int) -> Int,函数类型其实就是将函数的 “参数类型” 和 “返回值类型” 抽象出来。 那么怎么给 c 这个变量赋值呢?具体写法如下所示:
val c: (Int, Int) -> Int = ::add
fun add(num1: Int, num2: Int): Int = num1 + num2
::add 这种写法是一种函数引用方式的写法。除了函数引用这种方式外,Kotlin 还支持用 Lambda 表达式对一个函数类型的变量进行赋值。如下所示:
val c: (Int, Int) -> Int = {num1: Int, num2: Int -> num1 + num2}
实际项目中,绝大多数情况下我们都是用 Lambda 表达式来调用高阶函数的。
Lambda 表达式语法结构:{参数名1: 参数类型, 参数名2: 参数类型 -> 函数体} 函数体中可以编写任意行代码,最后一行代码会自动作为 Lambda 表达式的返回值
了解了函数类型和高阶函数的定义,我们很简单的就可以定义高阶函数了,如下所示:
// 参数是函数类型的高阶函数
fun higherFunction(func: (Int, Int) -> Int) {
}
// 返回值是函数类型的高阶函数
fun higherFunction(): (Int, Int) -> Int {
}
(2)高阶函数传无参数函数
fun say() {
println("Hello World")
}
/**
* 在 Kotlin 中无返回为 Unit
*
* 此方法接收一个无参数的函数并且无返回
*
* 使用参数名加 () 来调用
*/
fun people(hello: () -> Unit) {
hello()
}
/**
* 在 kotlin 中有一个约定,如果最后一个参数是函数,可以省略括号
*/
fun main() {
people ({ say() })
people { say() }
}
运行程序打印“Hello World”,没有问题
(3)高阶函数传有参数函数
写法一:
fun say(msg: String) {
println("Hello $msg")
}
/**
* 当调用的函数有形参时,
* 需要在调用的函数声明,并使用声明的形参;
* 函数参数中的形参无法使用
*/
fun people(arg0: String, hello: (arg1: String) -> Unit) {
hello(arg0)
}
fun main() {
people("Android") {
say("World")
}
}
运行结果如下: 那么问题来了,传入的arg0似乎没有生效,我们来看看正常写应该咋写? 我们传参不写成Lambda表达式应该是下面这种: 编译器会提示我们优化,如上截图的下滑黄线,用鼠标放上去点即可,优化最后: 这才是正确的Lambda表达式写法,其实在编译器上看前一种写法也比较明显,在传入形参it后,我们重新付了一个值。 当然,不用Lambda表达式的写法如下,也是可以的: 查看运行结果:
问题总结
初步介绍了kotlin语言中,高阶函数传参将函数作为参数传递,抛砖引玉,有兴趣的朋友可以进一步深入了解。