Kotlin的函数和Lambda表达式

定义函数

fun 函数名(形参列表)[:(返回值类型列表)]{
//函数体
}
。下面定义了两个Int类型的参数,和一个Int类型的返回值

fun sum(a: Int, b: Int): Int {
return a + b
}
// 如果函数体是一个表达式的话,可以简写,返回类型自动推导
fun sum(a: Int, b: Int) = a + b

没有返回值的情况
省略[:返回值类型]部分,默认返回 Uint 类型,相当于 Java 的 void,和手动写上 :Uint 一样的

指定默认值

fun sum(a: Int = 4, b: Int = 6): Int {
return a + b
}

直接在形参类型后面使用 = 赋值。通常会把有默认值的参数放在最后

数量可变形参

使用 vararg 修饰,一个函数只能有一个 vararg 参数

fun sumOfNumbers(vararg numbers: Double, initialSum: Double): Double {
var sum = initialSum
for(number in numbers) {
sum += number
}
return sum
}

// Kotlin 允许通过名字来传入参数
sumOfNumbers(1.5, 2.5, initialSum=100.0) // Result = 104.0

使用已有数组传参,Spread Operator

val a = doubleArrayOf(1.5, 2.6, 5.4)
sumOfNumbers(*a) // Result = 9.5

函数变量

函数本身是一种数据类型,可以赋值给变量。赋值的时候使用 :: 获取函数的引用。

var myFunc = ::sumOfNumbers
myFunc(1.5, 2.5, initialSum=100.0) // Result = 104.0

myFunc = ::anotherFunc
myFunc("param1","param2")

函数形参

higher-order 高阶函数,就是一个函数的形参是另一个函数,或者返回一个函数就称为高阶函数

fun entry(data:Array<Int>, fn:(Int) -> Int):Array<Int>{
var ret = Array<Int>(data.size,{0})
//遍历data,使用fn做计算
for (i in data.indices){
ret[i] = fn(data[i])
}
return ret
}

fun square(n:Int) = n*n
fun cube(n:Int) = n*n*n
fun fact(n:Int):Int{
var ret = 1
for (idx in 2 .. n){
ret *= idx
}
return ret
}

fun main(args: Array<String>) {
var data = arrayOf(3,4,8,5,9)
println(entry(data,::square).contentToString())
println(entry(data,::cube).contentToString())
println(entry(data,::fact).contentToString())
}

函数返回值

Kotlin 支持本地函数(Local Functions),就是在一个函数体内定义的函数

fun mathFunc(type: String):(Int)-> Int{
fun square(n:Int) = n*n
fun cube(n:Int) = n*n*n
fun fact(n:Int):Int{
var ret = 1
for (idx in 2 .. n){
ret *= idx
}
return ret
}

when (type){
"square" -> return ::square
"cube" -> return ::cube
else -> return ::fact
}
}

var mf = mathFunc("cube")
println(mf(3))
println(mathFunc("square")(4))

单表达式

当函数返回单个表达式的时候,可以使用下面的写法

fun add(a:Int,b:Int) = a + b

返回类型声明是可选的,可以由编译器推导。

Lambda 表达式

可以简化语句。

max(strings, { a, b -> a.length < b.length })

这里 max 是高阶函数,接收一个函数值作为第二个参数,而第二个参数时一个函数的表达式,和下面的定义是等价的

fun compare(a: String, b: String): Boolean = a.length < b.length

Lambda 表达的语法

val sum = { x: Int, y: Int -> x + y }

首先必须有大括号 {} 包裹,参数声明在 -> 之前,函数体在 -> 后面。
最后一个表达式自动作为返回值。

如果表达式只有一个参数,隐含命名为 it

ints.filter { it > 0 } // this literal is of type '(it: Int) -> Boolean'

返回值

除了默认把最后一个表达式作为返回值外,还可以显示指定返回值。下面两个是等价的

ints.filter {
val shouldFilter = it > 0
shouldFilter
}

ints.filter {
val shouldFilter = it > 0
return@filter shouldFilter
}