函数
函数声明
与Java不同,Kotlin中使用fun关键字后跟函数名称来声明函数。“()”后的“:Int”表示返回值类型,如下:
fun methodName(param1: Int, param2: Int): Int {
return 0
}
参数默认值
Kotlin函数中参数可赋予默认值,如下:
fun methodName(param1: Int = 0, param2: Int = 1) {
println("param1 = $param1, param2 = $param2")
}
如果参数有默认值,则调用函数时,可不传该参数。调用方式及打印结果如下:
简化函数
函数返回单个表达式的结果时,如下初始函数:
fun largerNumber(num1: Int, num2: Int): Int {
val number = if (num1 > num2) {
num1
} else {
num2
}
return number
}
可以直接返回表达式的结果,简化如下:
fun largerNumber(num1: Int, num2: Int): Int {
return if (num1 > num2) {
num1
} else {
num2
}
}
并且,针对此类情景,可以将return关键字替换为赋值运算符,简化如下:
fun largerNumber(num1: Int, num2: Int): Int = if (num1 > num2) {
num1
} else {
num2
}
因为Kotlin的类型推导机制,该类函数也无需声明返回值类型,简化如下:
fun largerNumber(num1: Int, num2: Int) = if (num1 > num2) {
num1
} else {
num2
}
匿名函数
并非每个函数都需要一个名称。某些函数通过输入和输出更直接地进行标识。这些函数称为“匿名函数”。如下:
val stringLengthFunc: (String) -> Int = { input ->
input.length
}
在上面的示例中:stringLengthFunc 包含对一个匿名函数的引用,该函数将 String 当作输入,并将输入 String 的长度作为 Int 类型的输出返回。因此,该函数的类型表示为 (String) -> Int。不过,此代码不会调用该函数。要检索该函数的结果,必须像调用命名函数一样调用该函数。调用 stringLengthFunc 时,必须提供 String,如以下示例所示:
// 匿名函数引用(此代码不会调用该函数)
val stringLengthFunc: (String) -> Int = { input ->
input.length
}
// 调用匿名函数
val stringLength: Int = stringLengthFunc("Android")
高阶函数
定义:一个函数可以将另一个函数当作参数。将其他函数用作参数的函数称为“高阶函数”。此模式对组件之间的通信(其方式与在 Java 中使用回调接口相同)很有用。
先看一个普通函数,如下:
// 遍历数组,打印每个元素
fun forEachSample(array: Array<String>) {
for (value in array) {
println("value = $value")
}
}
声明高阶函数:还是上面例子中的函数,接收另一个参数-函数,如下:
fun forEachSample(array: Array<String>, action: (String) -> Unit) {
for (value in array) {
action(value)
}
}
调用高阶函数:可以传递一个 Array 和一个满足其他输入参数的函数,使用“::action1”来引用“action1()”函数,如以下示例所示:
val array = arrayOf("red", "green", "blue")
forEachSample(array, ::action1)
fun action1(str: String) {
println("value = $value")
}
或者使用匿名函数,如下:
val array = arrayOf("red", "green", "blue")
forEachSample(array, action = { value ->
println("value = $value")
})
简化高阶函数:如果函数是在某个函数上定义的最后一个参数,则您可以在用于调用该函数的圆括号之外传递它,如以下示例所示:
forEachSample(array) { value ->
println("value = $value")
}
有两个及以上参数是函数时,调用高阶函数,如下:
// 声明
fun Array<String>.forEachSample(action1: (String) -> Unit, action2: (Int) -> Unit) {
for ((pos, value) in this.withIndex()) {
action1(value)
action2(pos)
}
}
// 调用
val array = arrayOf("red", "green", "blue")
array.forEachSample(action1 = { value ->
println("value = $value")
}, action2 = { pos ->
println("position = $pos")
})
扩展函数
扩展是 Kotlin 的一种语言特性,即:在不修改类 / 不继承类的情况下,向一个类添加新函数或者新属性。扩展使我们可以合理地遵循开闭原则,在大多数情况下是比继承更好的选择。
声明扩展函数,声明一个String的扩展函数,打印该String属性的长度:
//函数名称前加“.String”,如果是Int的扩展函数,则加“.Int”
fun String.printlnLength() {
println("str长度 = ${this.length}")
}
调用扩展函数:
// 必须是String类型才可以调用该函数
"red".printlnLength()
声明数组扩展函数,遍历数组,例:
fun Array<String>.forEachSample() {
for (value in this) {
println("value = $value")
}
}
// 调用函数
val array = arrayOf("red", "green", "blue")
array.forEachSample()
扩展函数与高阶函数结合使用,修改如下:
fun Array<String>.forEachSample(action: (String) -> Unit) {
for (value in this) {
action(value)
}
}
//调用扩展函数
val array = arrayOf("red", "green", "blue")
array.forEachSample { value ->
println("value = $value")
}
将String替换为泛型T,使任意类型的数组都可以调用该扩展函数,修改如下:
fun <T> Array<T>.forEachSample(action: (T) -> Unit): Unit {
for (value in this) {
action(value)
}
}
最后,看一下数组、集合自带的forEach扩展函数: