Kotlin函数

时间:2020-02-23 14:37:30  来源:igfitidea点击:

在本教程中,我们将详细讨论Kotlin中的功能。
我们将讨论从语法到各种实现的所有您需要了解的有关kotlin函数的知识。

Kotlin函数

在Kotlin中,可以在顶层使用功能。
在顶层,我们的意思是可以定义它们而无需将其封装在类中或者任何地方。
这是在Kotlin中我们使用术语函数而不是方法的主要原因之一。

功能类型

可以根据各种类别将功能定义为各种类型。
在很高的层次上,我们在以下两类中定义函数。

按范围

  • 顶级函数:这些不需要包含类。

  • 成员函数:这些是在类或者对象内定义的

  • 局部或者嵌套函数:在另一个函数中定义的函数属于此类型。

根据定义

  • Kotlin标准函数:Kotlin在标准库中定义了自己的一组函数,例如main()println()等。

  • 用户定义的函数:我们在项目中编写的函数。

Kotlin函数基本语法

Kotlin中的功能很有趣!无疑,功能是使用关键字" fun"定义的。
其后是函数名称。
参数及其类型放在方括号内。
返回类型设置在括号之外,如下所示。

fun function_name(param1: Type1, param2: Type2,.....) : SetReturnTypeHere{
  //function body goes here.
}

注意:要覆盖子类中的函数,我们需要附加修饰符" override"

声明和用法

让我们定义一个计算两个数字之和的函数。
我们将在范围定义的每种类型中执行此操作。

  • 顶级功能
    要调用该函数,我们只需要传递参数作为参数即可。

  • 会员职能
    成员函数在类内部定义。
    成员函数使用点运算符在类的实例上调用,如下面的代码所示。

  • 本地/嵌套功能
    我们可以在另一个函数中定义一个函数。
    它也可以是封闭函数的返回类型。

下面的代码演示了相同的内容。

letMeDoubleAndAdd()执行部分并将结果返回给第一个函数。

注意:上面代码中的print函数隐含了sumOfDoubleOfTwo()函数。
因此," sumOfDoubleOfTwo()"在第二条语句中充当嵌套函数。

单位返回类型

如果没有返回类型,我们可以将返回类型空间留空。

fun main(args: Array<String>) {
  
  sumOfTwo(2,3) //returns 5

}

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

  return a + b
}

什么是kotlin.Unit?在Java中,"单位"与Kotlin等效于"无效"。
所以上面的函数也可以写成:

fun main(args: Array<String>) {

  var a = A()
  a.sumOfTwo(2,3)

}

class A {

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

      return a + b
  }
  
}

尽管我们不必设置上面的定义,因为设置Unit返回类型不是强制性的。

默认和命名参数

Kotlin允许在函数定义中设置默认值。
这样,如果您未在函数调用中传递参数,则将使用默认值,如下所示。

fun main(args: Array<String>) {

   sumOfDoubleOfTwo(2,3) //returns 5
   print(sumOfDoubleOfTwo(2,3)) //prints 10. This is a triple nested function.

}

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

  fun letMeDoubleAndAdd(): Int {
      return a * 2 + b * 2
  }

  return letMeDoubleAndAdd()
}

命名参数使我们可以将参数名称设置为函数调用中相应的参数。
这样,我们可以始终设置自己的顺序,而不必始终遵循参数的定义顺序。
如下所示,它也增强了功能的可读性。

fun main(args: Array<String>) {

  helloWorld() //prints Fun says hello world
  print(helloWorld()) //prints Fun says hello world\nkotlin.Unit

}

fun helloWorld() {
  println("Fun says hello world")
}

在上面的代码中,我们可以跟踪函数中每个参数的名称和值,而与下面的代码不同,我们可以忘记为哪个参数设置了哪个参数。

fun helloWorld() :Unit {
  println("Fun says hello world")
}

单表达函数

使用以下语法,可以使Kotlin中仅包含一个表达式的函数更加简单明了:

fun main(args: Array<String>) {

  print(appendAllParams("Hi", message = "How are you doing?")) //prints Hi Jay, How are you doing?

}

fun appendAllParams(greet: String, name: String = "Jay", message: String): String {
  return greet + name + ", " + message
}

如上所示,单个表达式可以写在=的右侧。
单表达式函数不需要设置返回类型或者花括号。
Kotlin会自动为您推断。

可变参数个数– varargs

我们可以使用参数声明中的'vararg'修饰符在Kotlin中使用可变数量的参数定义函数,如下所示。

fun main(args: Array<String>) {

  returnBooleans(a = true, b = true, c = true, d = false)
}

fun returnBooleans(a: Boolean, b: Boolean, c: Boolean, d: Boolean): Boolean {
  return a && b || c && d
}

她的函数只允许使用一个vararg参数。

作为类型的功能

在Kotlin中,我们可以将函数用作类型并将其分配给属性,将其作为参数传递给其他函数,或者将它们用作返回值(高阶函数)。

returnBooleans(true, true, true, false)

函数类型是一个强大的概念,我们将在高级函数中对其进行详细介绍。

点差算子

散布运算符用*表示,并将数组分解为单个元素,我们最终将其传递给vararg参数,如下所示。

fun main(args: Array<String>) {

  print(sumOfTwo(2, 3))
}

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

" intArrayOf"会从元素中创建一个数组,并将其传递到" sumOfNumbers"函数中,该函数最终会将数组扩展为" vararg"。

扩展功能

扩展功能用于将某些功能扩展到类。

fun main(args: Array<String>) {
  print(concatenate("Hello\n", "How are you doing?\n", "Add more words in here\n"))
}

fun concatenate(vararg word: String): String {

  var result = ""

  for (s in word) {
      result += s
  }

  return result
}

在类中,我们始终可以从类扩展函数,如下所示:

fun main(args: Array<String>) {
  val str = concatenate("Hello\n", "How are you doing?\n", "Add more words in here\n") 
  //str is of type String
}

fun concatenate(vararg word: String): String {

  var result = ""

  for (s in word) {
      result += s
  }

  return result
}

在上面的代码中,扩展函数使类中的成员函数过载。

中缀符号

在函数上添加了前缀表示法,以使函数调用更简洁,更接近英语,因为我们不需要像稍后将看到的那样使用点符号来调用函数。
要求:

  • 在function关键字之前添加infix修饰符
  • 它仅适用于成员或者扩展功能
  • 一个中缀函数只能有一个参数

下面的示例对此进行了演示。

fun main(args: Array) {
  val a = intArrayOf(1, 2, 3)
  print(sumOfNumbers(*a))

}

fun sumOfNumbers(vararg numbers: Int): Int {
  var sum = 0
  for (number in numbers) {
      sum += number
  }
  return sum
}

从上面的代码中,我们可以判断出位运算符andor等是kotlin中的中缀函数。
此外,downTo中使用了中缀符号功能,直到Kotlin中的循环中也使用了etc

尾递归函数

尾递归函数是Kotlin用来摆脱递归函数循环的模板。
在函数中添加" tailrec"修饰符会将函数写为递归函数,而无需for/while循环,从而降低了堆栈溢出的风险。
通常,我们可以编写如下的递归函数:

fun main(args: Array<String>) {
  var x = 5

  print(x.multiplyByTwo()) //10
}

fun Int.multiplyByTwo() : Int
{
return this*2
}

使用tailrec,上面的函数应如下所示:

fun main(args: Array<String>) {
  val b = Book()
  b.printFunction("Hey") //member function
  b.printFunction() //extension function
}

fun Book.printFunction()
{
  println("Extension")
}

class Book {
  fun printFunction(str: String) {
      println(str)
  }
}

//Following is printed on the console
//Hey
//Extension

注意:tailrec仅在递归调用后没有代码时才有效。

创建阶乘尾递归函数

通常,阶乘函数是这样编写的:

fun main(args: Array<String>) {
  val b = Numbers()
  b addNumber 5

  print(b.x) //prints 15
}

class Numbers {

  var x = 10
  infix fun addNumber(num: Int) {
      this.x = this.x + num
  }
}

尾递归函数如下所示:

fun findFixPoint(): Double {
  var x = 1.0
  while (true) {
      val y = Math.cos(x)
      if (x == y) return x
      x = y
  }
}