语言学习——kotlin

Kotlin——函数与Lambda表达式

2023-09-25  本文已影响0人  So_ProbuING

函数是执行特定任务的一段代码。Kotlin对Java的面向对象进行了弥补,增加了函数式编程的支持

函数入门

定义和调用函数

定义函数的语法格式:

fun 函数名(形参列表)[:返回值类型]{
    //由零条到多条可执行语句组成的函数
}

Kotlin声明函数必须使用fun关键字

函数名:首字母小写符合命名规范
返回值类型:可以是Kotlin语言所允许的任何数据类型。如果希望声明一个函数没有返回值,则:
省略:省略返回值部分
使用Unit指定返回Unit代表没有返回值 Unit就相当于Java中的void
形参列表:形参列表用于定义该函数可以接受的参数,形参列表由多组“形参名:参数类型”组合而成,之间用","隔开

fun main(args: Array<String>) {
    println(max(2, 5))
    println(sayHi("abcdefg"))
}
fun max(x: Int, y: Int): Int {
    var max = if (x > y) x else y
    return max
}

fun sayHi(name:String):String{
    println("=====正在执行sayHi函数=====")
    return "hello ${name}"
}

函数返回值和Unit

fun main(args: Array<String>) {
    foo()
    sayHiNull("dddd")
}

fun foo() {
    println("foo()函数")
}

fun sayHiNull(name : String): Unit{
    println("sayHi函数")
    println("welcome${name}")
}

递归函数

在一个函数体内调用自身,称为递归函数,函数递归包含了一种隐式的循环,它会重复执行某段代码而无须循环控制

fun fn(n: Int): Int {
    if (n == 0) {
        return 1
    } else if (n == 4) {
        return 4
    } else {
        return 2 * fn(n - 1) + fn(n - 2)
    }
}

单表达式函数

函数只是返回单个表达式,此时可以省略花括号并在=后制定函数体

fun area(x:Int,y:Int):Int = x*y

函数的形参

默认值

语法:

形参名:形参类型=默认值

个数可变的形参

Kotlin允许定义个数可变的参数,从而允许为函数指定数量不确定的形参。在定义函数时,在形参的类型前面添加vararg修饰,则表明该形参可以接受多个参数值。多个参数值被当成数组传入

fun bookStore(a: Int, vararg books: String) {
    //books被当成数组处理
    for (book in books) {
        println(book)
    }
    println(a)
}

kotlin要求一个函数最多只能带一个个数可变的形参,但是对个数可变的形参位置没有要求

函数重载

与Java类似,Kotlin允许定义多个同名函数,只要形参列表或返回值类型不同就行。如果程序包含了两个或两个以上函数名相同,但形参列表不同的函数,就称为函数重载

fun test() {
    println("无参数的test函数")
}

fun test(name: String){
    println("有一个String参数的test函数")
}

fun test(age:Int){
    println("有一个int参数的test函数")
}
fun test(name:String,age:Int):String{
    return "有2个参数带返回值的函数"
}

局部函数

在Kotlin函数体内部定义的函数,放在函数体内定义的函数称为局部函数
局部函数对外部是隐藏的,局部函数只能在封闭函数内有效

//定义函数,该函数的返回值类型为 Int
fun qetMathFunc(type: Strinq , nn: Int) : Int {
//定义一个计算平方的局部函数
fun s伊are (n: Int) : Int { //①
return n * n
//定义一个计算立方的用部函数
fun cube(n: Int) : Int { //②
return n * n * n
//定义一个计算阶乘的局部函数
fun factorial(n: Int) : Int { //③
var result = 1
for (index in 2 .. n) {
result *= index
return result
when(type) {
//调用局部函数
” square”-> return square(nn)
” cube" -> return cube(nn)
else-> return factorial(nn)}

高阶函数

函数本身也具有自己的类型,函数类型既可以用于变量,也可用作函数的形参,还可以作为函数的返回值类型

使用函数类型

Kotlin的每个函数都有特定的类型,函数类型由函数的形参列表、->和返回值类型组成

fun foo(a:Int,name:String) -> String{}

该函数的函数类型就是 (Int,String)->String

fun bar(width:Double,height:Double){}

该函数的类型:(Double,Double)->Unit或(Double,Double)

fun test(){}

该函数的类型 () 或 ()->Unit

//定义一个变量,其类型为(Int,Int)->Int
var myfun : (Int,Int)->Int

可将函数赋值给变量

fun main(args: Array<String>) {
    var myfun = ::pow
    println(myfun(3, 5))
    myfun = ::areaa
    println(myfun(3, 4))
}

fun areaa(a:Int,b:Int):Int{
    return a * b
}

/**
 * 定义一个计算乘方的函数
 */
fun pow(base:Int,exponent:Int):Int{
    var result =1
    for (i in 1..exponent){
        result *= base
    }
    return result
}

使用函数类型作为形参类型

如果希望调用函数时能动态传入代码,就需要在函数中定义函数类型的形参,这样可以在调用该函数时传入不同的函数作为参数。从而动态改变这些代码

fun main(args: Array<String>) {
    var data = arrayOf(3, 4, 5, 6, 7, 8)
    println(map(data, ::square))
    println(map(data, ::add))
}

fun map(data: Array<Int>, fn: (Int) -> Int): List<Int> {
    //创建一个新的数组
//    Array<Int>(data.size,{0})
    val mutableList = mutableListOf<Int>()
    for (index in data.indices) {
        mutableList.add(index, fn(data[index]))
    }

    return mutableList
}

fun square(n: Int): Int {
    return n * n
}

fun add(n: Int): Int {
    return n + 1
}

使用函数类型作为返回值类型

fun main(args: Array<String>) {
    var mathFunc = getMathFunc("square")
    println(mathFunc(3))
    var cubeFun = getMathFunc("cube")
    println(cubeFun(3))
}


/**
 * 获取数学函数
 */
fun getMathFunc(type:String):(Int) -> Int{
    //定义平方
    fun square(n:Int):Int{
        return n * n
    }
    //定义计算立方
    fun cube(n:Int):Int{
        return n*n*n
    }
    //定义计算阶乘
    fun factorial(n:Int):Int{
        var result = 1
        for (i in 2..n) {
            result *=i
        }
        return result
    }

    return when (type) {
        "square" -> ::square
        "cube" -> ::cube
        else -> ::factorial
    }
}

局部函数与Lambda表达式

使用Lambda表达式代替局部函数

上面的函数我们可以使用Lambda表达式来进行改造

when (type) {
        "square" -> return {n:Int->n*n}
        "cube" -> return {n:Int -> n*n*n}
        else -> return {n:Int ->
            var result = 1
            for (i in 2..n) {
                result *=i
            }
            result
        }
    }

Lambda的特点:

Lambda表达式

Lambda表达式的语法:

{
  (形参列表)->
//零条到多条可执行语句
}

利用上下文推断类型

完整的Lambda表达式需要定义形参类型,如果Kotlin可以根据Lambda表达式上下文推断出形参类型,那么Lambda表达式可以省略形参类型

var square:(Int)->Int = {n -> n*n}

省略形参名

Lambda表达式如果只有一个形参,那么Kotlin允许省略Lambda表达式的形参名,如果省略了形参名,那么此时 ->也不需要了,可以使用it来代表形参

var square:(Int) -> Int = {it*it}

调用Lambda表达式的约定

Kotlin语言约定,如果函数的最后一个参数是函数类型,且打算传入一个Lambda表达式作为相应的参数,那么就允许在圆括号之外指定Lambda表达式

var rt = list.dropWhile(){it.leng>3}

匿名函数

用法

var test = fun(x:Int,y:Int):Int{
  return x+y
}
上一篇 下一篇

猜你喜欢

热点阅读