Kotlin语法总结:函数类型和高阶函数
Posted LQS_Android
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin语法总结:函数类型和高阶函数相关的知识,希望对你有一定的参考价值。
函数类型
参数列表中的参数类型 -> 返回类型
//定义计算长方形面积函数
//函数类型 (Double, Double) -> Double
fun rectangleArea(width: Double, height: Double): Double { ①
return width * height
}
//定义计算三角形面积函数
//函数类型 (Double, Double) -> Double
fun triangleArea(bottom: Double, height: Double) = 0.5 * bottom * height ②
//函数类型 ()->Unit ③
fun sayHello() {
print("Hello, World")
}
fun main(args: Array<String>) {
//定义一个函数类型为(Double, Double)->Double的常量,通过函数引用方式初始化
val getArea: (Double, Double) -> Double = ::triangleArea ④
//调用函数
val area = getArea(50.0, 40.0) ⑤
print(area) //1000.0
}
解释已经在注释中,这里不再解释。
函数字面量
//在函数体中定义函数,kotlin是可以的,但Java不可以
fun calculate(opr: Char): (Int, Int) -> Int {
//定义加法函数
fun add(a: Int, b: Int): Int {
return a + b
}
//定义减法函数
fun sub(a: Int, b: Int): Int {
return a - b
}
val result: (Int, Int) -> Int = when (opr) {
'+' -> ::add //①加法函数引用
'-' -> ::sub //②减法函数引用
'*' -> {
//乘法匿名函数
fun(a: Int, b: Int): Int { ③
return (a * b)
}
}
else -> { a, b -> (a / b) } //除法Lambda表达式 ④
}
return result
}
fun main(args: Array<String>) {
val f1 = calculate('+') //⑤f1的变量类型是函数类型(Int, Int) -> Int
println(f1(10, 5)) //调用f1变量
val f2 = calculate('-') //⑥f2的变量类型是函数类型(Int, Int) -> Int
println(f2(10, 5))
val f3 = calculate('*') //⑦f3的变量类型是函数类型(Int, Int) -> Int
println(f3(10, 5))
val f4 = calculate('/') //⑧f4的变量类型是函数类型(Int, Int) -> Int
println(f4(10, 5))
}
//定义计算长方形面积函数
//函数类型 (Double, Double) -> Double
fun rectangleArea(width: Double, height: Double): Double { ①
return width * height
}
//定义计算三角形面积函数
//函数类型 (Double, Double) -> Double
fun triangleArea(bottom: Double, height: Double) = 0.5 * bottom * height ②
fun getArea(type: String): (Double, Double) -> Double {
//定义函数类型变量
var returnFunction: (Double, Double) -> Double
when (type) {
//rect 表示长方形
"rect" -> returnFunction = ::rectangleArea
//tria 表示三角形
else -> returnFunction = ::triangleArea
}
return returnFunction
}
fun main(args: Array<String>) {
//定义area函数变量,初始化赋值,获得计算三角形面积函数
var area: (Double, Double) -> Double = getArea("tria")
println("底10 高13,计算三角形面积:${area(10.0, 15.0)}")
//获得计算长方形面积函数
area = getArea("rect")
println("宽10 高15,计算长方形面积:${area(10.0, 15.0)}")
}
上述代码定义函数getArea,其返回类型是(Double, Double) -> Double, 这说明返回值是一个函数类型。声明了一个returnFunction变量,显式指定它的类型是(Double, Double) -> Double函数类型。在when表达式中,在类型type为rect(即 长方形)的情况下,把rectangleArea函数引用赋值给returnFunction变量,这种赋值之所以能够成功是因为returnFunction类型是(Double, Double) -> Double函数类型。下一行else情况的代码一样不再解释。最后将returnFunction变量返回。
在main函数中调用函数getArea,返回值area是函数类型变量。area(10,15)调用函数其参数列表是(Double, Double)。
上述代码运行结果如下:
底10 高15,计算三角形面积:75.0
宽10 高15,计算长方形面积:150.0
高阶函数:函数作为参数使用
//高阶函数,funcName参数是函数类型
fun getAreaByFunc(funcName: (Double, Double) -> Double, a: Double, b: Double): Double {
return funcName(a, b)
}
fun main(args: Array<String>) {
//获得计算三角形面积函数
var result = getAreaByFunc(::triangleArea, 10.0, 15.0)
println("底10 高15,计算三角形面积:$result")
//获得计算长方形面积函数
result = getAreaByFunc(::rectangleArea, 10.0, 15.0)
println("宽10 高15,计算长方形面积:$result")
}
上述代码定义函数getAreaByFunc,它的第一个参数funcName是函数类型 (Double, Double) -> Double,第二个和第三个参数都是Double类型。函数的返回值是Double类型,是计算几何图形面积。
底10 高15,三角形面积:75.0
宽10 高15,计算长方形面积:150.0
经过前文的介绍总结,你会发现函数类型也没有什么难理解的,与其他类型的用法一样。
内联函数
在高阶函数中参数如果是函数类型,则可以接收Lambda表达式,而Lambda表达式在编译时被编译称为一个匿名类,每次调用函数时都会创建一个对象,如果这种被函数反复调用则创建很多对象,会带来运行时额外开销。
为了解决次问题,在Kotlin中可以将这种函数声明为内联函数,内联函数在编译时不会生成函数调用代码,而是用函数体中实际代码替换每次调用函数。
//内联函数 函数类型作为参数
inline fun calculatePrint(funN: (Int, Int) -> Int) {
println("${funN(10, 5)}")
}
fun main(args: Array<String>) {
calculatePrint { a, b -> a + b }
calculatePrint { a, b -> a - b }
}
使用let函数
fun square(num: Int): Int = num * num //函数参数是一个非空的整数
fun main(args: Array<String>) {
val n1: Int? = 10 //变量n1是一个可空的变量
//在调用square()函数之前,需要自己进行非空判断
if (n1 != null) {
println(square(n1))
}
}
自己判断一个对象非空比较麻烦。在Kotlin中任何对象都可以调用一个let函数,let函数后面尾随一个Lambda表达式,在对象非空时执行Lambda表达式中的代码,为空时则不执行。
fun square(num: Int): Int = num * num //函数参数是一个非空的整数
fun main(args: Array<String>) {
val n1: Int? = 10 //变量n1是一个可空的变量
n1?.let { n -> println(square(n)) }
//使用隐式it代替参数n,所以简化效果如下
n1?.let { println(square(it)) }
}
class MyFrame(title: String) : JFrame(title) {
init {
// 创建标签
val label = JLabel("Label")
// 创建Button1
val button1 = JButton() ①
button1.text = "Button1"
button1.toolTipText = "Button1"
// 注册事件监听器,监听Button1单击事件
button1.addActionListener { label.text = "单击Button1" } ②
// 创建Button2
val button2 = JButton().apply { ③
text = "Button2"
toolTipText = "Button2"
// 注册事件监听器,监听Button2单击事件
addActionListener { label.text = "单击Button2" }
// 添加Button2到内容面板
contentPane.add(this, BorderLayout.SOUTH)
} ④
with(contentPane) { ⑤
// 添加标签到内容面板
add(label, BorderLayout.NORTH)
// 添加Button1到内容面板
add(button1, BorderLayout.CENTER)
println(height)
println(this.width)
} ⑥
// 设置窗口大小
setSize(350, 120)
// 设置窗口可见
283isVisible = true
}
}
fun main(args: Array<String>) {
//创建Frame对象
MyFrame("MyFrame")
}
以上是关于Kotlin语法总结:函数类型和高阶函数的主要内容,如果未能解决你的问题,请参考以下文章