Kotlin

Kotlin基础二(函数)

2022-04-02  本文已影响0人  KevinGarnett21

  再长的路,一步步也能走完,再短的路,不迈开双脚也无法到达。


  今天学习了下函数,与Java相同的函数定义以及方法就省略了,今天主要讲下Kotlin中独有的函数或者与Java不同的地方(部分还没有学习到,后续再补充),开干。

一. 函数语法

函数声明  函数名称([参数名称:参数类型,参数名称:参数类型]):返回值类型{ 
    执行语句 
    … 
    return 返回值 
}

二. 单表达式函数

如果函数体中只有一行代码,则可以把包裹函数体的花括号{}替换为等号“=”,把函数体放在等号“=”的后面,这样的函数称为单表达式函数

fun add(a: Int, b: Int): Int = a + b
// 单表达式还可以省略函数的返回值类型
fun add(a: Int, b: Int) = a + b

三. 函数参数

1. 具名参数

指在调用函数时显示指定形参的名称,这样即使形参和实参的顺序不一致也不会有任何影响,因为已经明确指定了每个形参对应的实参,这样有助于提高代码的可读性

class Person(val name: String,val age : Int)

fun main() {
    val person = Person(name = "张三",age = 18)
}

2. 默认参数

概念:指在定义函数时,可以给函数中的每一个形参指定一个默认的实参

优势:可以减少重载数量

class Student(val name : String = "张三",val age: Int)

fun main() {
    val student = Student(age = 18)
}

注意:当覆盖⼀个有默认参数值的⽅法时,必须从签名中省略默认参数值

open class A {
    open fun foo(i: Int = 10) {}
}

class B : A() {
    override fun foo(i: Int) {} // 不能有默认值
}

3. 可变参数

可变参数通过vararg关键字标识,我们可以将其理解为数组。可变参数通常声明在形参列表中的最后位置,如果不声明在最后位置,那么可变参数后面的其他参数都需要通过命名参数的形式进行传递。

// 可变参数
class Num(vararg num : Int) {
    //初始化
    init {
        var result = 0
        // 循环
        num.forEach {
            result+= it
        }
        println("result:$result")
    }
}

// 调用方式
val num = Num(1,2,3)

由于可变参数实质上就是数组,因此,可以直接使用数组存放可变参数,在传递时使用数组即可,这样更加直观方便。

// 传递数组
val intArr = intArrayOf(1,2,3)
// 注意要使用*展开数组(注意只能展开数组,不能展开集合)
val num2 = Num(*intArr)

总结-Kotlin中的可变参数与Java中的可变参数的对比

Kotlin中可变参数规则:

  1. 可变参数可以出现在参数列表的任意位置;
  2. 可变参数是通过关键字vararg来修饰;
  3. 可以以数组的形式使用可变参数的形参变量,实参中传递数组时,需要使用“*”前缀操作符。

Java中可变参数规则:

  1. 可变参数只能出现在参数列表的最后;
  2. 用“…”代表可变参数,“…”位于变量类型与变量名称之间;
  3. 调用含有可变参数的函数时,编译器为该可变参数隐式创建一个数组,在函数体中以数组的形式访问可变参数。

3. Kotlin特有函数

1. 顶层函数

顶层函数又称为包级别函数,可以直接放在某一个包中,而不像Java一样必须将函数放在某一个类中,函数可以独立存在;如果在同一个包中,可直接调用,如果在不同的包中,需要导入对应的包

package com.example.kotlindemo.basic
// 顶层函数
fun top() {
    println("顶层函数")
}

2. 局部函数

一个函数在另一个函数内部,内部函数可以调用外部函数

// 局部函数
fun part(name: String) {

    val test: Int = 0

    fun segment(name: String) {
        println("可以访问局部变量:${test}")
    }
}

3. 递归函数&尾递归函数

1) 递归函数: 递归函数指的是在函数体内部调用函数本身

// 递归函数
fun sum(num : Int) : Int {
    return if (num == 1) {
        num
    } else {
        num+sum(num-1)
    }
}

2) 尾递归函数: 如果一个函数中所有递归调用都出现在函数的末尾,我们称这个递归函数是尾递归函数。<u>通常情况下,尾递归函数一般用在连续求和、连续求差等程序中。</u>

// 尾递归函数
fun tailSum(num : Int,total : Int = 0) : Int {
    return if (num == 1) {
        1 + total
    } else {
        tailSum(num - 1,num+total)
    }
}

3)尾递归函数优化:Kotlin中提供了一个tailrec修饰符来修饰尾递归函数,此时编译器会优化该尾递归函数,将尾递归函数转化为while循环,程序会快速高效地运行,并且无堆栈溢出的风险。

// 尾递归函数优化
tailrec fun tailRecSum(num: Int, total: Int = 0): Int {
    return if (num == 1) {
        1 + total
    } else {
        tailRecSum(num - 1, num + total)
    }
}

调用结果

fun main() {
    println("递归函数:${sum(4)}")
    // 直接报错:StackOverflowError
    println("尾递归函数:${tailSum(100000)}")
    // 结果:705082704
    println("尾递归函数优化:${tailRecSum(100000)}")
}

4. 中缀函数

中缀函数总是要求指定接收者与参数

class InfixTest {

    private infix fun test(str : String ) = println(str)

    fun build() {
        test("adb")
        this test "adb"
    }
}

书籍:《Kotlin从基础到实战》、Kotlin官方文档

上一篇下一篇

猜你喜欢

热点阅读