Kotlin进阶:屠龙术第一式

120 阅读2分钟
  • 文章摘要:本文从多个角度,以实际使用为出发点探究了KT部分语言精华,为系列专题第一篇文章;涵盖了:函数参数拒收、函数覆写,KT中三元运算符同等替换,if 语句在KT与 Java中的对比,扩展函数配合匿名函数与配合显示函数、附带了几个常用例子进一步展示KT语言的魅力

Kotlin 中函数参数拒收

  • 在Lamda(匿名函数实现体)中,使用 _ 拒收对应位置的参数

  • 代码

     fun main(){
         var method : (Int,Int) -> Unit = {_,number2 ->
             println("传入的第二个参数是:$number2")
         }
         method(1,2)
     }
    
  • 运行结果:

    image-20220607215135115

Kotlin 中三元表达式的替换(if-else)

  • 三元表达式:

    • 格式:if(条件) ?业务代码一 :业务代码二
    • 当条件为true,执行业务代码一,false则执行业务代码二
  • KT中的 == 与 ===

    • ==:相当于 Java中的equals,用于值比较
    • ===:用于引用对象的比较
  • Kotlin代码:在KT中 if 为表达式,可灵活返回;Java中 if 为语句,不可返回

     fun main(){
         var method : (Char) -> Unit ={
             sex: Char-> if(sex == '男') println("这是男生") else if(sex == '女') println("这是女生") else println("性别未知")
         }
         method('男')
         method('空')
     }
    
  • 运行结果:

    image-20220607215951503

Kotlin 中匿名函数覆盖

  • 对一拥有完整声明与实现的匿名函数,进行重新赋值;

  • 注意覆写之后:原函数执行逻辑被修改(原函数实现体报灰)但无法改变原函数返回值(相关代码报灰,因为原函数返回值为Unit,且匿名函数具有隐式返回特性,若最后一行不报灰,则函数的返回值被修改)

  • 代码:覆写之前

     fun main(){
         var method = {number: Int -> println("传入的值为:$number")}
         method(5)
         println(method(5))//会调用method并且打印method的返回值
     }
    
  • 运行结果:覆写之前

    image-20220607220710462

  • 代码:覆写之后(报灰)

    image-20220607221418753

  • 运行结果:

    image-20220607221243112

关于函数默认参数

  • 匿名函数不允许对参数设置默认值

    • 正常情况:

      image-20220607222238968

    • 异常情况:期望设置参数默认值

      image-20220607222314333

需求:打印传入参数并且返回参数

  • 代码:

     fun main(){
     //    需求:打印传入参数并且返回参数
         var method : (String) -> String = { str ->
             println("传入的参数是:$str")
             str
         }
         method("WAsbry")
     }
    
  • 运行结果:

    image-20220607222619479

扩展函数:为现有框架无伤注入自定义API

  • 工作机制:

    • 为系统String类,注入新功能(匿名函数实现体中的业务逻辑),相当于新增了API
    • 且在匿名函数实现体中默认持有this,指向被注入的对象(类、框架)
    • String类的任意对象,均可采用 . 调用这个新功能
  • 匿名函数注入代码:

     fun main(){
     //    扩展函数
         var method : String.() -> Unit = {
             println("调用者为:$this")
         }
     ​
         "WAsbry".method()
     }
    
  • 匿名函数注入运行结果:

    image-20220607223114941

  • 显示注入:

    • 好处:

      • 因为KT代码是默认public static也就是全局公开的;那么可以在项目的任意位置写扩展函数,对现有的系统类/框架进行无伤注入自定义API
      • 扩展函数中以this,指代调用者
      • 同时也可以修改扩展函数的修饰符,达到访问受限功能
      • 在compose源码中,就是使用的扩展函数实现的
    • 工程结构:

      image-20220607224106602

    • 代码展示:utils.kt

       package Utils
       ​
       fun String.show(){
           println("调用者为:$this")
       }
      
    • 代码展示:zjob.kt

       package zjob
       ​
       import Utils.show
       ​
       fun main(){
           "WAsbry".show()
       }
      
    • 运行结果:

      image-20220607224227853

扩展函数实际使用:两数相加

  • 工作机制:

    • this指代调用者Int,it指代匿名函数的唯一实参
  • 代码:

     fun main(){
         var method : Int.(Int) -> String = { "两数相加的结果为:${this + it}" }
         println(method(1, 2))
         println(1.method(2))
     }
    
  • 运行结果:

    image-20220607225021412

扩展函数:三数相加(解决it 局限性)

  • it局限性:

    • 当匿名函数只有一个入参时,默认采用it指代
    • 但匿名函数入参个数大于1时,it失效
  • 代码:

     fun main(){
     //    三数相加
         var method : Double.(Double,Double) -> Unit = {d1,d2 ->
             println("三数相加的结果为:${ this + d1 + d2 }")
         }
         1.1.method(2.2,3.3)
     }
    
  • 运行结果:

    image-20220607225613923

扩展函数:替代三元表达式

  • 前置知识:扩展函数隐式注入,KT匿名函数、三元运算符、隐式返回、println源码,匿名函数隐式指代

  • 匿名函数的隐式返回

    • 默认最后一行为返回值,当最后一行为另一函数时,其返回值作为匿名函数的返回值

    • println的返回值为Unit

      image-20220607234157875

  • 代码:

     fun main(){
     //    性别判断
         var method : Char.(String) -> Unit = {
             println(if(this == '男') "这是男生" else if(this == '女') "这是女生" else "匿名函数的实际参数是:$this")
         }
         '女'.method("WAsbry")
         '空'.method("WAsbry")
     }
    
  • 运行结果:

图片.png