Kotlin 函数的一些特殊用法

Kotlin函数声明:

private fun testFunction(funName: String = 'test function'): Unit {
    println('test Function' + funName)
}

其中函数可见性修饰符默认public,public函数可以省略修饰符。

 函数声明关键字`fun`必须。

函数名`testFunction `必须。

Unit函数:

函数默认值参数funName和参数类型String。

Unit作为Kotlin中的特殊的函数类型,相当于其它语言中的void函数,函数中没有return关键字,那么此函数就是Unit函数,函数返回Unit,但函数没有任何返回值。

与viod不同,viod不返回任何内容。而Unit则可以和其它一些类型进行交互

fun main() {
    val name = "---  Kotlin ----  "
    val testUnit : () -> Unit = {
        println("!testUnit function!")
    }

    println(name + testUnit())
}

上面匿名函数运行后返回 

!testUnit function!
---  Kotlin ----  kotlin.Unit

不会报错。

Nothing函数:

同样还有其它不会返回任何值的函数,比如Nothing函数

与Unit函数不同,Nothing意味着函数不会执行成功,,它要么抛出异常,要么因为其它原因导致程序不会回到函数调用处。

通常用于异常处理。

public inline fun TODO():Nothing = throw Error()

函数重载:

函数可以在同一个类或子类及其父类中定义多个同名函数

fun main() {

    val funNumber = 2
    val funName = "funName"
    testFunction()
    testFunction(funName)
    testFunction(funName, funNumber)

}

public fun testFunction(): Unit {
    println("test Function")
}

public fun testFunction(funName: String) {
    println("test function " + funName)
}

public fun testFunction(funName: String, funNumber: Number) {
    println("test function $funName $funNumber")
}

同过传递不同参数调用不同testFunction函数。

单表达式函数:

单表达式的特殊写法

fun main() {

    testFunction()
    println( testAddOperatorFunction(3, 2) )
}

fun testFunction(): Unit = println("test Function")
fun testAddOperatorFunction(num1:Int,num2:Int) = num1 + num2

假如函数只有一个表达式语句,或者只有一条求值语句,那么函数的返回类型、花括号、返回语句都可以省略。

匿名函数:

fun main() {
    //匿名函数1
    println({" Hello World "}()) 

    //匿名函数2
    val testUnit : () -> Unit = {
        println("!testUnit function!")
    }

    testUnit()
}

匿名函数定义就是把程序语句放在`{}`中,匿名函数后面使用`()`表示执行函数调用。

定义变量时,实在变量后面跟上冒号和类型,而testUnit : () -> Unit 则表示任何空不需要参数并返回Unit类型的函数都可以赋值给testUnit

it关键字:

定义只有一个参数的匿名函数时,可以使用it关键字

    val testUnit : (String) -> Unit = {
        println("$it !testUnit function!")
    }

    testUnit("hello")

但如果匿名函数有多个参数,那么it关键字就不能用了。

    val testUnit : (String, Int) -> Unit = { UserName, Number ->
        println("$UserName, $Number !testUnit function!")
    }

    testUnit("hello", 666)

lambda表达式:

lambda表达式属于匿名函数的一种,

{x: Int, y:Int -> x + y}

lambda表达式始终被“{}"包围,->"左边为函数参数,右边是函数体。

lambda可以作为参数到处传递

 println({title:String, descript:String -> " Hello World $title $descript"}("Lambda", "表达式"))
fun main() {
    //作为参数传递
    testLambda({title:String, descript:String -> " Hello World $title $descript"})
}

fun testLambda(olambda: (title:String, description:String) -> Unit) {
    val title = "lambda";
    val description = "表达式"
    println(olambda(title, description))
}

如果一个函数的lambda参数排在最后,或者是唯一参数,那么括lambda参数的小括号就可以省略

fun main() {
    //简略语法
    testLambda {title:String, descript:String ->  "Hello $title $descript" }
}

函数内联(inline):

在JVM上,lambda是以对象实例的形式存在,因此,JVM会为所有lambda打交道的变量分配内存。并且,lambda的内存开销非常影响性能。

而kotlin提供一种叫做“内联”的机制解决lambda引起的内存消耗,有了内联,JVM就不再需要使用lambda对象实例。

使用函数内联,只需要以inline标记使用lambda函数的函数即可:

fun main() {
    //简略语法
    testLambda {title:String, descript:String ->  "Hello $title $descript" }
}
//函数内联
//使用inline标记函数
inline fun testLambda(olambda: (title:String, description:String) -> String) {
    val title = "lambda";
    val description = "表达式"
    println(olambda(title, description))
}

需要注意的是,使用lambda的递归函数无法内联。

函数引用:

除了lambda表达式,kotlin还允许使用传递函数引用。

函数引用可以把一个具名函数转换成一个值参,凡是使用lambda表达式的地方,都可以使用函数引用:

fun main() {
    //使用操作符::将具名函数作为参数传递
    testLambda(::printCurrentYear) {title:String, descript:String ->  "Hello $title $descript" }
}

inline fun testLambda(printYear: KFunction1<String, Unit>, olambda: (title:String, description:String) -> String) {
    val title = "lambda";
    val description = "表达式"
    printYear(title)
    println(olambda(title, description))
}

fun printCurrentYear(userName: String) {
    print("$userName 2024 \n")
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值