kotlin函数汇总

2023-01-10  本文已影响0人  Jack921

这篇主要讲讲kotlin里面的各种函数

fun myMethod()= print("jack")

就这样,一句代码的时候就直接用=就可以实现,或者在单行表达式时:

 fun myMethod2(count:Int)=if(count>2) {
    var data=myMethod()
    "jack1$data"
} else {
    "jack2"
}
  1. 定义时不取名字的函数,我们称之为匿名函数,匿名函数通常整体传递给其他函数或者从其他函数返回
  2. 和函数不一样,匿名函数通常不需要return关键字返回数据。匿名函数会隐式的或自动返回最后一行代码的执行结果。
val myMethod:()->String={
    "jack"
}

fun main(){
    myMethod
}

这样就可以直接调,当又参数时:

//单个参数
val myMethod:(name:String)->String={
    it+"jack"
}
//多个参数
val myMethod:(name:String,age:Int)->String={n:String,a:Int->
    n+"jack"+a
}

当我们把匿名函数赋值给变量时,也可以不用指定函数的返回值类型,有编译器进行类型推断。

//没有参数
val myMethod={
    "jack"
}

//一个参数时:
val myMethod={name:String->
    name+"jack"
}

//多个参数时:
val myMethod={name:String,age:Int->
    name+"jack"+age
}

fun test(name:String,age:Int,getAge:(age:Int)->String){
    var data=name+getAge(age)
    Log.e("test",data)
}

fun main(){
    test("Jack",12){
        it.toString()+"你好"
    }
}

输出的结果为 E/test: Jack12你好, 也可以独立出一个匿名函数:

val getAgeFun:(age:Int)->String={
    it.toString()+"你好"
}
fun test():(age:Int)->Int{
    var a = 1//状态
    return {
        var data=a+it
        Log.e("test",data.toString())
        data
    }
}

fun main(){
  val funTest=test()
  funTest(1)
  funTest(2)
  funTest(3)
  funTest(4)  
}

函数内部的局部变量的状态保存了,变量的值就是状态,而返回值可以闭包捕获的变量可以脱离原始作用域而存在:

fun test5():()->Int{
    var a = 1//状态
    return {
        a++
        Log.e("test",a.toString())
        a
    }
}
fun test1(name:String,age:Int){
    fun test2(ageTest:Int):String{
        return ageTest.toString()
    }
    var data=test2(age)
    println(name+data)
}

fun main(){
    test1("jack",12)
}

运行结果System.out: jack12

// Test.kt
fun test(string: String) {
    println("this is top function for $string")
}

这种函数可以在 Kotlin 中被直接调用,无需指定其实例或类名.

data class Person(var name: String, var age: Int)

operator fun Int.minus(p: Person) =  this - p.age

可以被重载运算符

表示 重载
a = a + b a = a.plus(b)
a = a - b a = a.minus(b)
a = a * b a = a.tiems(b)
a = a / b a = a.div(b)
a = a % b a = a.rem(b)
a … b a.rangTo(b)
a % b a.rem(b) 或 a.mod(b)
++a, a++ inc
!a not
a > b a.compareTo(b) > 0
a < b a.compareTo(b) < 0
a >= b a.compareTo(b) >= 0
a in b b.contains(a)
a !in b !b.contains(a)

Kotlin中的 && 、 || 、 ?: 、 === 、 !== 是不能被重载的

inline
用inline 修饰的方法,当又地方调用它时,把这个函数方法体中的所以代码移动到调用的地方,而不是通过方法间压栈进栈的方式,可以提高代码效率,当时也会照常编译的时候代码臃肿。

inline fun test(){
    println("inline fun")
}

fun main(){
    test()
}

在实际的编译后,其实代码变成如下这样:

fun main(){
    println("inline fun")
}

这样看还不知道内联函数有啥优势,毕竟这么做虽然会提高点运行效率,但是也会造成编译代码变多,那为啥要有内联函数呢?,先看如下代码:

inline fun test(printAction:()->Unit){
    println("inline fun")
    printAction()
}

fun main(){
    test{
        println("hello")
    }
}

我们用高阶函数定义了一个printAction()函数,但是printAction()是一个对象,假如我们一个for循环不断调用test(printAction:()->Unit)方法,那就会产出很多printAction()函数对象,这也会短时间造成内存大量消耗,加上inline,上面的函数实际编译成如下:

fun main(){
    println("inline fun")
    println("hello")
}

这样就减少了函数对象的创建,节省的内存的消耗。

noinline
我们用inline定义函数之后,假如想让一些函数里的代码不直接移动到调用的地方,还是想像普通函数一样要咋办,就可以noinline 来修饰函数,不参加内联了:

inline fun test(noinline printAction:()->Unit){
    println("inline fun")
    printAction()
}

fun main(){
    test{
        println("hello")
    }
}

实际编译成如下:

fun main(){
    println("inline fun")
    ({
        println("hello")
    }).invoke()
}

crossinline
刚才讲的 noinline 是局部关闭内联优化,而这个crossinline,是局部加强内联优化。

//普通函数是不能直接return
private fun test1( printAction:()->Unit){
    println("simple fun")
    printAction()
}

//内联函数可以直接return
private inline fun test2(printAction:()->Unit){
    println("inline fun")
    printAction()
}

private inline fun test3(crossinline printAction:()->Unit){
    println("crossinline fun")
    printAction()
}


fun main(){
    test1 {
        println("fun1")
        return //编译报错
    }
    
    test2 {
        println("fun2")
        return //编译正常
    }
    
     test3 {
        println("fun3")
        return //编译报错
    }
    
}

crossinline 关键字就像一个契约,它用于保证内联函数的Lambda表达式中一定不会使用return全局返回,保证内联函数只能在最外层返回,而不能再别的地方放回,例如:

inline fun test4(func1: () -> Unit) {
    runOnUiThread {
        func1()  //编译器报错
    }
}

小结:

  1. kotlin只允许内联函数的函数参数内部有return,普通函数的函数参数内部不能有return
  2. crossinline让编译器帮我们检查函数参数内部是不是带有return,有的话直接在IDE提醒我们不能写(还是为了满足结论1,禁止函数参数写return)
上一篇下一篇

猜你喜欢

热点阅读