ZetCode

Kotlin 函数

最后修改于 2024 年 1 月 29 日

在本文中,我们将展示如何在 Kotlin 语言中使用函数。

函数是将零个或多个输入值映射到零个或多个输出值。通过函数,我们可以减少代码重复并提高其清晰度。更复杂的任务可以使用函数分解成更简单的单元。函数可以分配给变量,作为参数传递给函数或从其他函数返回。

函数签名 是 Kotlin 编译器的函数的唯一标识。 签名由函数名称、其参数和返回类型组成。

Kotlin 中的函数使用 fun 关键字声明。 函数体称为块,用 { } 大括号括起来。 函数可以使用 return 关键字返回值。

命名函数

任何合法字符都可以在函数名称中使用。 按照惯例,函数名称以小写字母开头。 函数名称是动词或动词后跟形容词或名词。 每个后续单词以大写字母开头。 以下是 Kotlin 中函数的典型名称

Kotlin 对函数名称使用 lowerCamelCase 约定。 其他编程语言可能使用 CamelCasesnake_case

Kotlin main 函数

main 函数是 Kotlin 程序的入口点。

Main.kt
package com.zetcode

fun main() {

    println("main function is an entry point")
}

程序在终端上打印一条简单的消息。

fun main() {

    println("main function is an entry point")
}

这是 Kotlin 程序的入口点。 main 函数不接受任何参数。

Main.kt
package com.zetcode

fun main() {

    val sumVal = args.map { it.toInt() }.sum()
    println("The sum of values is $sumVal")
}

在此示例中,程序接受参数;我们假设是字符串整数。 我们将这些字符串转换为整数并计算它们的总和。 请注意,sumprintln 也是函数;它们是 Kotlin 内置函数。

Kotlin 内置函数

Kotlin 标准库附带许多内置函数。

Main.kt
package com.zetcode

import kotlin.random.Random

fun main() {

    println("There is a majestic hawk in the sky")

    val r = Random.nextInt(0, 100)
    println(r)

    val word = "ocean"
    val letters = word.toCharArray()

    letters.forEach(::println)
}

该示例展示了四个 Kotlin 内置函数。

println("There is a majestic hawk in the sky")

println 函数在终端上输出数据。

val r = Random.nextInt(0, 100)

Random.nextInt 函数从指定的范围内返回一个随机值。

val letters = word.toCharArray()

toCharArray 函数将字符串中的所有字符以数组形式返回。

letters.forEach(::println)

forEach 函数遍历数组的值。

There is a majestic hawk in the sky
29
o
c
e
a
n

Kotlin 函数返回值

函数可以返回值。 要返回值,我们使用 return 关键字。

Main.kt
package com.zetcode

fun square(x: Int): Int {

    return x * x
}

fun square2(x: Int): Int = x * x


fun main() {

    println(square(5))
    println(square2(6))
}

在该示例中,我们有两个 square 函数。

fun square(x: Int): Int {

    return x * x
}

当函数有一个用大括号括起来的函数体时,它使用 return 关键字返回值。

fun square2(x: Int): Int = x * x

return 关键字不用于具有表达式体的函数。

Kotlin 函数参数

Kotlin 中的函数可以接受参数。 参数在 括号内指定并用逗号分隔。 函数参数使用 Pascal 标记法定义,即 name: type。 必须显式键入每个参数。

Main.kt
package com.zetcode

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

fun main() {

    val r = sum(4, 3)
    println(r)
}

在该示例中,我们有一个自定义的 sum 函数。

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

sum 函数返回其两个参数的总和。 参数和返回值都是整数。

val r = sum(4, 3)

调用 sum 函数,并将返回值分配给 r 变量。

Kotlin 函数默认参数值

Kotlin 函数参数可以有默认值;如果未提供参数值,则使用这些默认值。

Main.kt
package com.zetcode

fun power(a: Int, b: Int = 2): Int {

    if (b == 2) {

        return a * a
    }

    var value = 1

    repeat(b) {
        value *= a
    }

    return value;
}

fun main() {

    val r1 = power(3)
    println(r1)

    val r2 = power(3, 3)
    println(r2)
}

我们创建了一个 power 函数。 该函数有一个带有隐式值的参数。 我们可以使用一个或两个参数调用该函数。

9
27

Unit 返回类型

Kotlin 函数必须指定其返回类型;例外情况是它们不返回任何值。 void 的返回类型是 Unit;可以省略此类型。

Main.kt
package com.zetcode

fun showGreeting(name: String): Unit {

    println("Hello $name")
}

fun main() {

    showGreeting("Arnold")
    showGreeting("Lucia")
}

该示例显示了问候语。

fun showGreeting(name: String): Unit {

    println("Hello $name")
}

showGreeting 函数在终端上打印一条消息;它不返回任何内容。 因此,返回类型指定为 Unit

Hello Arnold
Hello Lucia

Kotlin 单表达式函数

当函数的函数体包含单个表达式时,可以省略大括号,并在 = 符号后指定函数体。

Main.kt
package com.zetcode

fun double(num: Int): Int = num * 2
fun triple(num: Int) = num * 3

fun main() {

    val r1 = double(3)
    val r2 = triple(3)

    println(r1)
    println(r2)
}

该示例包含两个单表达式函数。

fun double(num: Int): Int = num * 2

该函数返回参数乘以 2。 省略大括号和 return 关键字。

fun triple(num: Int) = num * 3

可以省略返回类型;它由 Kotlin 推断。

可变数量的参数

函数可以接受可变数量的参数。 为此,我们使用 vararg 关键字。

Main.kt
package com.zetcode

fun mysum(vararg vals: Int): Int {

    return vals.sum()
}

fun main() {

    val s1 = mysum(1, 2, 3)
    val s2 = mysum(1, 2, 3, 4)
    val s3 = mysum(1, 2, 3, 4, 5)

    println(s1)
    println(s2)
    println(s3)
}

我们创建一个 mysum 函数,它可以接受可变数量的参数。 该函数计算传递给函数的值的总和。

fun mysum(vararg vals: Int): Int {

    return vals.sum()
}

通过使用 vararg 关键字,mysum 函数可以接受可变数量的参数。 vals 变量是一个 Kotlin 数组。

val s1 = mysum(1, 2, 3)
val s2 = mysum(1, 2, 3, 4)
val s3 = mysum(1, 2, 3, 4, 5)

我们调用 mysum 函数三次。 每次参数的数量都不同。

6
10
15

Kotlin 函数递归

递归,在数学和计算机科学中,是一种定义函数的方式,其中所定义的函数在其自身的定义中应用。 换句话说,递归函数调用自身来完成其工作。 递归是解决许多编程任务的常用方法。

一个典型的例子是计算阶乘。

Main.kt
package com.zetcode

fun fact(num: Int): Int {

    return if (num == 1) {
        num
    } else {
        num * fact(num - 1)
    }
}

fun main() {

    val f1 = fact(5)
    val f2 = fact(8)
    val f3 = fact(12)

    println(f1)
    println(f2)
    println(f3)
}

在此代码示例中,我们计算了三个数字的阶乘。

num * fact(num - 1)

fact 函数的函数体内部,我们使用修改后的参数调用 fact 函数。 该函数调用自身。

120
40320
479001600

这些是结果。

Kotlin 匿名函数

匿名函数是没有名称的函数。 匿名函数通过消除创建单独函数的需要来减少编码开销。

Main.kt
package com.zetcode

fun main() {

    val vals = intArrayOf(-2, -1, 0, 1, 2, 3, 4)

    val filtered = vals.filter(fun(el) = el > 0)
    println(filtered)
}

我们有一个整数数组。 使用 filter 函数过滤数组。 它将匿名函数作为参数。

val filtered = vals.filter(fun(el) = el > 0)

匿名函数用于过滤数组。

[1, 2, 3, 4]

我们过滤掉了负值。

Kotlin 闭包

闭包是可以在函数范围之外定义的函数访问和修改属性的函数。

Main.kt
package com.zetcode

fun makeAverager(): (n: Int) -> Double {

    val nums = arrayListOf<Int>()

    return fun(num: Int): Double {

        nums.add(num)
        val total = nums.sum()

        return total.toDouble() / nums.size
    }
}


fun main() {

    val avg = makeAverager()

    println(avg(1))
    println(avg(2))
    println(avg(3))
    println(avg(4))
    println(avg(5))
}

该示例创建一个函数,该函数计算添加值的平均值。 它使用一个匿名函数,该函数从值列表中计算平均值。 匿名函数可以访问 nums 列表,该列表存储值,并在匿名函数的函数体之外定义。

1.0
1.5
2.0
2.5
3.0

Kotlin 局部函数

局部函数定义在其他函数内部。

Main.kt
package com.zetcode

fun main() {

    fun buildMessage(name: String?): String {

        return "Hello $name"
    }

    print("Enter your name: ")
    val name = readLine()

    val message = buildMessage(name)
    println(message)
}

在该示例中,我们有一个局部函数 buildMessage,它在 main 函数内部定义和调用。

Kotlin 扩展函数

扩展函数是可以在不需从现有类型派生类的情况下添加到现有类型的函数。 扩展函数像普通成员函数一样调用。 扩展函数允许我们向不是由我们创建的类添加功能,并且在继承不可能或没有意义时使用。

Main.kt
package com.zetcode

fun String.second(): Char = this[1]

fun main() {

    val word = "falcon"
    println(word.second())
}

该示例向 String 类型添加一个新函数。 该函数返回字符串的第二个字符。

Kotlin 成员函数

成员函数是在 Kotlin 类中定义的函数。

Main.kt
package com.zetcode

class Cat {

    fun talk() {
        println("meow")
    }
}

fun main() {

    val missy = Cat()
    missy.talk()
}

talk 函数定义在 Cat 类中。

val missy = Cat()
missy.talk()

我们创建 Cat 对象并使用点运算符调用成员函数。

Kotlin 高阶函数

高阶函数是将函数作为参数或返回函数的函数。

Main.kt
package com.zetcode

fun process(data: IntArray, f: (IntArray) -> Any): Any {

    return f(data)
}

fun main() {

    val values = intArrayOf(1, 2, 3, 4, 5, 6)

    val res1 = process(values, IntArray::sum)
    println(res1)

    val res2 = process(values, IntArray::average)
    println(res2)
}

在该示例中,我们有 process 高阶函数,它接受两个参数:一个整数数组和一个函数。 该函数应用于数组的元素。

fun process(data: IntArray, f: (IntArray) -> Any): Any {

    return f(data)
}

process 高阶函数将该函数应用于 data 数组。

val res1 = process(values, IntArray::sum)
println(res1)

我们将 IntArray's sum 函数传递给 process 函数。

Kotlin 中缀函数

可以使用所谓的 中缀表示法 调用函数。 中缀表示法是用于在视觉上改进代码的语法糖。 该表示法省略了点和括号。 有几个内置函数可以使用中缀表示法调用,例如 toandmatches

使用 infix 关键字创建中缀函数。 它们必须是成员函数或扩展函数,它们必须只有一个参数,并且该参数不能接受可变数量的参数并且不能有默认值。

Main.kt
package com.zetcode

fun main() {

    val a = true
    val b = false

    var res: Boolean

    res = a and b // a.and(b)
    println("a and b = $res")

    res = a or b // a.or(b)
    println("a or b = $res")
}

在该示例中,我们使用中缀表示法中的 andor 函数。

a or b = true
a and b = false
Main.kt
package com.zetcode

fun main() {

    val regex = Regex("[tT]rue|[yY]es")
    val values = arrayOf("yes", "no", "YES", "True", "null", "")

    values.forEach { value ->
        if (value matches regex) println("$value matches")
        else println("$value does not match")
    }
}

在该示例中,我们使用中缀表示法中的 matches 函数。

以下示例创建一个自定义的中缀函数。

Main.kt
package com.zetcode

class Builder {

    infix fun square(n: Int) {

        for (i in 1.. n) {

            println("0".repeat(n))
        }
    }
}

fun main() {

    val builder = Builder()
    builder square 4
    println()

    builder square 6
}

该示例创建一个中缀 square 函数,该函数在终端上输出一个矩形。

builder square 4

我们使用中缀表示法调用 square 函数。 它输出一个宽度和高度均为四个单位的矩形。

来源

Kotlin 函数 - 文档

在本文中,我们介绍了 Kotlin 函数。

作者

我的名字是 Jan Bodnar,我是一位热衷于编程并拥有丰富编程经验的程序员。 自 2007 年以来,我一直在撰写编程文章。 迄今为止,我撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出 所有 Kotlin 教程