关于Kotlin 中函数的一些思考

153 阅读3分钟

本文重点:

  • 概述:Kotlin中的函数如何编写?函数如何拆解,什么是匿名函数,什么是具名函数,什么是函数引用,匿名函数怎么写,匿名函数如何调用,匿名参数如何接收,it关键字的作用与失效场景,匿名函数中的隐式返回是什么?

Kotlin中的函数:

  • Kotlin中的函数并不依赖与类:函数可以写在类外面,甚至写在函数里面

  • 函数的声明:

     fun fuc(name: String){
         println("传入的参数name:$name")
     }
    

Kotlin 中的匿名函数

  • 匿名函数:没有名字的函数,代码中大括号包裹的内容

  • 代码:

     fun main(){
         val  len = "Hello".count()
         println(len)
         //这个括号就是匿名函数,内部默认持有it,指代调用者(字符串)中的每一个字符
         val lenOfL = "Hello".count(){
             it == 'l'
         }
     ​
         println(lenOfL)
     }
     ​
    
  • 运行结果:

    image-20220529140913029

Kotlin 中的函数类型与隐式返回:函数拆解

  • 拆解过程:函数的声明、函数的实现、函数的调用
  • 拆解细节:隐式返回(匿名函数不能写return)

    • 当函数的实现为匿名函数,最后一行默认为返回值
  • 代码:

     fun main(){
         //常规函数处理
         fun action() : String{
             return "action"
         }
         println("调用常规函数:${action()}")
     ​
         //将上述函数进行拆解
         //函数的声明,()的作用:为了对接函数的输入
         val action2 : () -> String
         //函数的实现
         action2 = {
             "action2"
         }
         //函数的调用
         println("调用拆解后的函数:${action2()}")
     }
    
  • 运行结果:

    image-20220529141909766

Kotlin 中的函数参数与匿名函数

  • 细节:

    • 在输入时,仅需指定参数类型与参数个数
    • 在函数实现(大括号)内,使用变量逐个进行接收
  • 代码:将匿名函数的声明与实现放在一起

     package step2
     ​
     fun main(){
         //常规实现
         fun factor(number1 : Int,number2 : Int,number3 : Int) : String {
             return "参数一:$number1,参数二:$number2,参数三:$number3"
         }
         println("调用常规实现:${factor(1,2,3)}")
     ​
         //采用匿名函数进行实现
         val factor2 : (Int,Int,Int) -> String = {number1,number2,number3 ->
             "参数一:$number1,参数二:$number2,参数三:$number3"
         }
         println("调用匿名函数:${factor2(1,2,3)}")
     }
    
  • 运行结果:

    image-20220529143023320

Kotlin 中的it关键字特点

  • 细节

    • 当匿名函数只有一个入参时,系统使用it进行指代;

      image-20220529144055290

    • 但入参多余一个,it失效

      • 当匿名函数入参为两个时的正确写法

        image-20220529144312228

      • 当匿名函数入参为两个时,使用it报错

        image-20220529144510545

    • invoke关键字用与不用没有什么区别的

      • 函数名.invoke(参数)
      • 函数名(参数)
  • 代码:

     package step2
     ​
     fun main(){
         //it关键字的实现效果
         val action: (String) -> String = {
             "$it"
         }
         println("测试it关键字:${action("hello")}")
     ​
         //it关键字的对应代码
         fun action2(it : String) : String{
             return it
         }
         println("it关键字的实现:${action2("hello")}")
     }
    
  • 运行结果:

    image-20220529143907390

Kotlin 中的匿名函数的类型推断

  • 概述:

    • 常规写法:指定了入参与返回值类型

    • 简略写法:由类型推断确定返回值

      • 需要在函数实现中指定参数类型
  • 代码:

     package step2
     ​
     fun main(){
         //常规写法
         val action : (Int,Int) -> Int = { number1,number2 ->
             number1
         }
         println("常规写法:${action(1,2)}")
         //省略写法
         val  action1 = {number1 : Int,number2 : Int->
             number1
         }
         println("省略写法:${action1(1,2)}")
     }
    
  • 运行结果:

    image-20220529145417098

Kotlin 中的匿名函数与Lamda

  • 概述:

    • 匿名函数可以认为是Lamda,但有点区别
    • Lamda的返回值类型为Any,而匿名函数的返回类型不局限与Any
  • 代码:返回类型为Any

     package step2
     ​
     //匿名函数与Lamda
     fun main(){
         val action = { number : Int ->
             when(number){
                 1 -> "一"
                 2 -> "二"
                 else -> -1
             }
         }
         println(action(2))
         println(action(5))
         
     ​
     }
    
  • 运行结果:

    image-20220529150411242

Kotlin 中函数返回类型为函数

  • 代码

     package step2
     ​
     //函数A返回值是匿名函数B
     fun main(){
         //backValue是show函数的返回值,其本身为一匿名函数
         val backValue = show("test")
         //调用这个匿名函数
         println(backValue("WAsbry",200))
     }
     ​
     fun show(string: String):(msg: String,code: Int) -> String{
         return {name: String,code: Int ->
             "姓名:$name,状态码:$code"
         }
     }
    
  • 运行截图:

图片.png

Kotlin 中的匿名函数与具名函数

  • 什么是匿名函数,什么是具名函数

    • 匿名函数:没有名字的函数
    • 具名函数:有名字的函数
  • 应用场景:

    • Kotlin:当函数参数为Lamda时,可以采用具名或匿名两种方式进行调用
    • Java:当函数参数为接口实例时,可以采用具名或匿名两种方式进行调用
  • 代码:Kotlin

     package step2
     ​
     //Kotlin 中的匿名函数与具名函数
     ​
     fun main(){
         //匿名函数调用:在调用处编写匿名函数实现体
         showPersonInfo("WAsbry",99){
             println("匿名函数调用的结果str为:$it")
         }
     ​
         //具名函数调用:单独为Lamda参数编写函数实现体并配合函数引用
         showPersonInfo("WAsbry",99,::showResultImpl  )
     ​
     }
     ​
     fun showResultImpl(result: String){
         println("具名函数调用的结果str为:$result")
     }
     ​
     inline fun showPersonInfo(name: String,score: Int,showResult: ( String)->Unit){
         val str = "name: $name,score: $score"
         showResult(str)
     }
    
  • 运行结果:

    image-20220606155235193

  • 代码:Java

     package step2;
     ​
     //采用接口模拟Lamda
     interface IShowResult{
         void result(String string);
     }
     ​
     public class KT34 {
         public static void main(String[] args) {
             //匿名函数--->采用接口处理
             showRersonInfo("WAsbry", 99, new IShowResult() {
                 @Override
                 public void result(String string) {
                     System.out.println("匿名函数调用的结果为:" + string);
                 }
             });
     ​
             //具名函数:新建一个类实现接口,采用多态接口实例化为新建类的对象,进而调用接口实例
             IShowResult iShowResult = new MshowResultImpl();
             showRersonInfo("WAsbry",99,iShowResult);
     ​
         }
     ​
         //新建类
         static class MshowResultImpl implements IShowResult{
             @Override
             public void result(String string) {
                 System.out.println("具名函数调用的结果为:" + string);
             }
         }
     ​
         //处理内联函数转换
         static void showRersonInfo(String name,int score,IShowResult iShowResult){
             String str = String.format("name:%s,score:%d",name,score);
             iShowResult.result(str);
         }
     }
    
  • 运行结果:Java

图片.png