Kotlin - 函数


Kotlin 是一种静态类型语言,因此函数在其中发挥着重要作用。我们对函数非常熟悉,因为我们在最后几章的示例中都使用了函数。函数是为执行特定任务而编写的代码块。所有现代编程语言都支持函数,它们也称为方法子例程

从广义上讲,函数接受一些称为参数的输入,对这些输入执行某些操作并最终返回一个值。

Kotlin 内置函数

Kotlin 提供了许多内置函数,我们在示例中使用了许多内置函数。例如print()println()是最常用的内置函数,我们用它们将输出打印到屏幕上。

例子

fun main(args: Array<String>) {
   println("Hello, World!")
}

用户定义函数

Kotlin 允许我们使用关键字fun创建自己的函数。用户定义的函数采用一个或多个参数,执行一项操作并将该操作的结果作为值返回。

句法

fun functionName(){  
   // body of function 
}  

一旦我们定义了一个函数,我们就可以在需要时调用它任意多次。以下是调用 Kotlin 函数的简单语法:

functionName()

例子

以下是定义和调用用户定义函数的示例,该函数将打印简单的“Hello, World!”:

fun main(args: Array<String>) {

   printHello()
   
}

fun printHello(){
   println("Hello, World!")
}

当你运行上面的 Kotlin 程序时,它将生成以下输出:

Hello, World!

功能参数

用户定义的函数可以采用零个或多个参数。参数为选项,可根据需要使用。例如,我们上面定义的函数没有使用任何参数。

例子

以下是编写用户定义函数的示例,该函数将添加两个给定数字并打印它们的总和:

fun main(args: Array<String>) {
   val a = 10
   val b = 20
   
   printSum(a, b)
   
}

fun printSum(a:Int, b:Int){

   println(a + b)
}

当你运行上面的 Kotlin 程序时,它将生成以下输出:

30

返回值

kotlin 函数根据要求返回一个值。同样,返回值是非常可选的。

要返回值,请使用return关键字,并在函数括号后指定返回类型

例子

以下是编写用户定义函数的示例,该函数将添加两个给定数字并返回总和:

fun main(args: Array<String>) {
   val a = 10
   val b = 20
   
   val result = sumTwo(a, b)
   println( result )
   
}

fun sumTwo(a:Int, b:Int):Int{
   val x = a + b
   
   return x
}

当你运行上面的 Kotlin 程序时,它将生成以下输出:

30

返回单位的函数

如果函数不返回有用值,则其返回类型为Unit。Unit 是一种只有一个值的类型,即Unit

fun sumTwo(a:Int, b:Int):Unit{
   val x = a + b
   
   println( x )
}

Unit 返回类型声明也是可选的。上面的代码相当于:

fun sumTwo(a:Int, b:Int){
   val x = a + b
   
   println( x )
}

Kotlin 递归函数

递归函数在许多场景中都很有用,例如计算数字的阶乘或生成斐波那契数列。Kotlin 支持递归,这意味着 Kotlin 函数可以调用自身。

句法

fun functionName(){  
   ...
   functionName()
   ...
}  

例子

以下是计算数字 10 的阶乘的 Kotlin 程序:

fun main(args: Array<String>) {
   val a = 4
   
   val result = factorial(a)
   println( result )
   
}

fun factorial(a:Int):Int{
   val result:Int
   
   if( a <= 1){
      result = a
   }else{
      result = a*factorial(a-1)
   }
   
   return result
}

当你运行上面的 Kotlin 程序时,它将生成以下输出:

24

Kotlin 尾递归

如果递归函数对自身的调用是其执行的最后一个操作,则该函数适合尾递归。

例子

以下是一个使用尾递归计算数字 10 的阶乘的 Kotlin 程序。这里我们需要确保乘法是在递归调用之前完成的,而不是之后。

fun main(args: Array<String>) {
   val a = 4
   
   val result = factorial(a)
   println( result )
   
}

fun factorial(a: Int, accum: Int = 1): Int {
    val result = a * accum
    return if (a <= 1) {
        result
    } else {
        factorial(a - 1, result)
    }
}

当你运行上面的 Kotlin 程序时,它将生成以下输出:

24
Kotlin 尾递归在计算阶乘或对大数进行其他处理时非常有用。因此,为了避免java.lang.StackOverflowError,必须使用尾递归。

高阶函数

高阶函数是采用另一个函数作为参数和/或返回一个函数的函数。

例子

以下是一个函数,它接受两个整数参数 a 和 b,此外,它还接受另一个函数操作作为参数:

fun main(args: Array<String>) {
   
   val result = calculate(4, 5, ::sum) 
   println( result )
   
}
fun sum(a: Int, b: Int) = a + b 

fun calculate(a: Int, b: Int, operation:(Int, Int) -> Int): Int {
    return operation(a, b)                                       
}

当你运行上面的 Kotlin 程序时,它将生成以下输出:

9

这里我们调用高阶函数,传入两个整数值和函数参数::sum。这里::是 Kotlin 中通过名称引用函数的表示法。

例子

让我们再看一个函数返回另一个函数的示例。这里我们定义了一个返回函数的高阶函数。这里(Int) -> Int表示平方函数的参数和返回类型。

fun main(args: Array<String>) { 
   val func = operation() 
   println( func(4) )
   
}
fun square(x: Int) = x * x

fun operation(): (Int) -> Int {
    return ::square                                       
}

当你运行上面的 Kotlin 程序时,它将生成以下输出:

9

Kotlin Lambda 函数

Kotlin lambda 是一个没有名称并用大括号 {} 定义的函数,它接受零个或多个参数和函数体。

函数体写在变量(如果有)后面,后跟 -> 运算符。

句法

{variable with type -> body of the function}  

例子

fun main(args: Array<String>) { 

   val upperCase = { str: String -> str.toUpperCase() }  

   println( upperCase("hello, world!") )
   
}                           

当你运行上面的 Kotlin 程序时,它将生成以下输出:

HELLO, WORLD!

Kotlin 内联函数

函数是用inline关键字声明的。内联函数的使用增强了高阶函数的性能。内联函数告诉编译器将参数和函数复制到调用站点。

例子

fun main(args: Array<String>) { 

   myFunction({println("Inline function parameter")})
   
}
inline fun myFunction(function:()-> Unit){
   println("I am inline function - A")

   function()
   
   println("I am inline function - B")
}                               

当你运行上面的 Kotlin 程序时,它将生成以下输出:

I am inline function - A
Inline function parameter
I am inline function - B

测验时间(面试和考试准备)

答案:D

解释

所有给定的关于 Kotlin 函数的陈述都是正确的

问题 2 - 以下程序的输出是什么:

fun main(args: Array<String>) {
   val a = 100000
   
   val result = factorial(a)
   println( result )
   
}

fun factorial(a:Int):Int{
   val result:Int
   
   if( a <= 1){
      result = a
   }else{
      result = a*factorial(a-1)
   }
   
   return result
}

A - 这将打印 0

B - 这只会引发警告

C - 编译将因错误而停止

D - 以上都不是

答案:C

解释

这将因 java.lang.StackOverflowError 停止,因为编译器无法调用大量递归函数。

答案:D

解释

关于尾递归的所有陈述 A、B 和 C 都是正确的。