前语:

前两篇文章介绍了Kotlin中的基本数据类型、特点和操控流。本篇文章咱们将介绍Kotlin中比较重要的一个知识点:函数。对于函数,我想每个开发同学都不会生疏。长于将杂乱的逻辑拆分成多个功能函数,将对咱们代码的可读性和可维护性会有很大的帮助。而将多个杂乱的逻辑放在同一个办法中,可能会让代码变得非常臃肿。下面让咱们开始本篇文章的学习。

1.函数的声明

在Kotlin中咱们用关键字fun来声明一个函数。一个简单的函数声明如下:

fun sum(left: Int, right: Int): Int {
        return left + right
}

关键字fun后边紧跟着函数名,一般函数名都是以这个函数完成的功能来命名的。函数名后紧跟着小括号(),界说该函数所需求的参数。即name:type。

多个参数用逗号隔开(name:type, name:type)。假如不需求参数,直接用()即可。假如该函数需求回来值则在()后边添加 :type。花括号{ }则代表这个函数的办法体或许说是这个函数的效果域。

2.函数的默许参数

一般在Java中函数咱们称之为办法,相比较Java言语,Kotlin中的函数答应有参数默许值。而答应办法的参数能够具有默许值,能够减少办法的重载(办法名相同,办法的参数类型和个数不同,咱们称之为办法的重载)。如下函数的界说:

fun sum(left: Int, right: Int): Int {
        return left + right
}
// right参数具有默许值0
fun sum(left: Int, center: Int, right: Int = 0): Int {
        return left +center + right
}

当咱们给sum函数的参数right添加了默许值以后。在函数调用的地方,咱们能够选择性的传或许不传这个参数。

fun main() {
    sum(0, 10)
    sum(0, 10, 15)
}
fun sum(left: Int, center: Int, right: Int = 0): Int {
    return left +center + right
}

长于运用函数参数的默许值,在实际开发过程中,能够减少像Java言语中的办法重载。

3.签字参数

当咱们调用一个具有很多参数的函数时,参数类型和参数名匹配起来比较费事时。签字参数的运用就变得很有含义。运用签字参数能够不必考虑参数在函数中声明的次序,运用propertyName = propertyValue的方法传入参数。假定咱们有如下具有多个参数的函数fold:

fun main() {
    fold(right = false, center = "center", left = 0, isEmpty = false)
}
fun fold(left: Int, center: String, right: Boolean, isEmpty: Boolean) {
    // ...省掉逻辑
}

fold函数具有4个参数,当咱们在main函数中运用签字参数的方法调用fold函数,咱们无需再考虑函数参数在声明时的方位,只要将一切的参数签字传入即可。当然在实际开发的过程中,一个杂乱函数的参数远不与此。

4.函数的默许回来值Unit

当一个函数没有回来值时,它将具有一个默许的回来值类型Unit。一般状况咱们都会省掉它。如下示例,咱们将fold函数的回来值显现的声明成Unit

fun fold(initValue: Int):Unit {
    // ...省掉逻辑
    return Unit
}
// 省掉Unit
fun fold(initValue: Int) {
    // ...省掉逻辑
    return 
}

回来时,咱们能够直接运用return,也能够显现的加上Unit回来值类型。

5.单函数表达式

在上一篇文章特点和操控流中咱们介绍到,当if或许when表达式的分支块中仅有一行表达式时,咱们能够省掉分支块的花括号。而Kotlin中的函数亦是如此。当函数回来单个表达式时,能够省掉花括号并且在=符号之后指定代码体即可:

fun sum(left: Int, right: Int): Int = left + right
// Kotlin编译器能够推断出函数的回来值类型,可省掉函数的回来值类型
fun sum(left: Int, right: Int) = left + right 

已然if或许when也能够作为单个表达式,那么咱们也能够将一个函数用=衔接一个if或许when的表达式。

fun isEmpty(str:String) = if(str.length == 0) true else false
// 示例代码
fun findNum(num:Int) = when(num) {
    1001 -> 0
    1002 -> 1
    else -> -1
}

6.可变数量的参数

在Java中咱们运用propertyType… propertyName的方法来声明一个可变数量的参数:

private void sum(Integer... value) {
        // ...
}

而在Kotlin中咱们运用关键字vararg来声明可变数量的参数。

fun main() {
    sum(1, 2, 3)
}
fun sum(vararg value:Int) {
    for(i in value) {
        println("i = $i")
    }
}
// 输出
i = 1
i = 2
i = 3

7.中缀表明法

在Kotlin中运用infix关键字润饰的函数能够运用中缀表明法,忽略该函数调用时的点和括号。该函数有必要满意如下条件:

  • 用infix润饰的函数有且只能有一个参数
  • 有必要是成员函数或许扩展函数(关于扩展函数后边会具体讲解)
  • 不能承受vararg声明的可变数量的参数

典型的运用,咱们能够看Kotlin中给咱们提供的Tuples.kt中的数据类Pair:

public data class Pair<out A, out B>(
    public val first: A,
    public val second: B
) : Serializable 
// ...
public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
// ...

由上面的代码中咱们能够看到数据类Pair具有infix润饰的扩展函数to -> A.to(that: B)。下面咱们来看一下在实际开发中的运用:

fun main() {
    val pair = 20 to "age"
    println("pair = $pair")
}
// 输出
pair = (20, age)

中缀表明法能够让咱们的函数调用像阅览英文相同的高雅。运用A to B的方法创立了一个Pair目标,省掉了调用函数时的点和括号。下面咱们运用infix关键字来完成一个咱们自己界说的函数:

infix fun <T> Collection<T>.has(item: T) = if (item in this) true else false
fun main() {
    val languageList = arrayListOf("kotlin", "ios", "android")
    if (languageList has "test") {
        println("There is this language")
    } else {
        println("There is no such language")
    }
}
// 输出
There is no such language

8.函数效果域

1.在Kotlin中函数能够在文件顶层声明。不需求像Java那样要创立一个类来保存一个函数。对与在文件顶层声明的函数默许状况下,咱们能够在当前文件地点的项目中恣意地方访问,除非你将函数显现的加上private访问润饰符。选中当前项目,右击鼠标或许触摸板。New -> Kotlin Class/File,在弹出的选择框中,咱们选择File,声明一个Fun.kt的文件。

// 当前项目中能够调用
fun sum(left: Int, right: Int): Int {
    return left + right
}
// 当前文件中能够运用
private fun fold() {
    println("fold called")
}

2.成员函数。

在类内部或许目标内部创立的函数咱们称之为成员函数,以点表明法调用。

class Student {
    fun study() {
        println("I enjoy learning")
    }
}
fun main() {
    Student().study()
}

3.部分函数。(在Kotlin中支撑一个函数嵌套其他一个函数)

在函数内部声明一个函数,咱们就称这个函数为部分函数。如下示例,咱们在main函数的内部声明了一个getMax函数。

fun main() {
    val a = 1001
    val b = 1002
    // 部分函数
    fun getMax() :Int {
        return if(a > b) {
            println("a = $a")
            a
        } else {
            println("b = $b")
            b
        }
    }
    println("max = ${getMax()}")
}
// 输出
b = 1002
max = 1002

部分函数能够访问外部函数声明的特点。

9.泛型函数

在Kotlin中咱们一般在关键字fun之后紧跟<T>来声明一个泛型函数。(大写字母放在<>中,T是习惯性写法,也能够用其他大写字母表明),如下:

fun <T> getData(data:T) {
    println("data = $data")
}

咱们也能够将声明的泛型类型作为函数的回来值:

fun <T> getData(data:T) :T {
    println("data = $data")
    return data
}

关于Kotlin中泛型的运用咱们会在后续的文章中具体介绍。

总结

到这里关于Kotlin中函数的介绍咱们就写完了,下篇文章咱们将具体介绍Kotlin中的高阶函数和Lambda表达式,咱们下期再会。