美文网首页Android开发经验谈Android开发程序员
Kotlin学习笔记之 19 高阶函数与 lambda 表达式

Kotlin学习笔记之 19 高阶函数与 lambda 表达式

作者: super_shanks | 来源:发表于2019-04-11 18:21 被阅读3次

19.高阶函数与 lambda 表达式

我们通常将函数作为参数或者返回值的函数成为高阶函数

  • 带接收者的函数类型

    在kotlin中我们,函数也是一种类型。比如() -> Int,这个表示无参的返回类型为整型的函数。(String, Int) -> Int表示需要两个参数StringInt,并且返回的Int的函数。

    这里要介绍的是带接收者的函数类型,比如String.(String) -> Int,其实也是需要两个参数,但是这样表达的好处是这个方法可以被当做拓展函数来使用。

    val stringPlus: String.(String) -> String = String::plus
    
      fun main() {
          stringPlus("1", "2")
          "1".stringPlus("2")
      }
    

    我们即可以直接传两个String到这个方法中去,也可以当成拓展函数来直接调用StringstringPlus方法,并且往里面传一个字符串。

    也就是String.(String)可以当成(String,String)来使用,而反过来则不行哦。

  • invoke方法

    invoke关键字跟在方法名后面,表示调用该方法,跟不加的效果是一样的,同上的例子

    println(stringPlus.invoke("<-", "->"))
    println(stringPlus("Hello, ", "world!"))
    

    invoke关键字还会用在类或者接口内的方法定义中

    class AA {
          companion object Factory {
              operator fun invoke (xxx: Any) = xxx
      
              fun test11(){}
          }
      
          operator fun invoke(dda : String) = "22"
      
          fun test(){
          }
      }
    

    我们在两个地方使用到了invoke,注意,我们直接通过操作符重载的方式可以定义类本身的构造方法。

    比如上面的伴生对象的invoke方法,就是重载了伴生对象的构造方法,即直接调用AA(xxx: Any)可以获得一个Any对象。

    或者我们走一个更加容易理解的方式,就是所有重载的invoke操作符,我们都可以通过对象.invoke(参数)的方式去调用,由于invoke又是可以省略的,所以我们可以直接通过对象(参数)的方式去调用

    //伴生对象(参数)直接使用
    val aaa: Any = AA(6)
    
     val aa: Unit = AA.test11()
    
     val bbb = AA()
    
     bbb.test()
     
     bbb.invoke("1")
     //对象(参数)
     bbb("1")
    
  • lambda中it的出现时机

    我们在前面讲过,通常高阶函数的定义和调用方式如下

    fun html( a : (String, Int, Short) -> String){
      }
      
    html {
          s, i, sh -> "test" 
      }
    

    由于高阶函数最后一个参数是函数,所以可以直接写在方法外,又由于只有一个函数参数,所以连括号都可以省去了。

    其次,我们传入函数的方式是,大括号,并且包括所有的参数自定义(一般为类型的大写字母,比如String就是sInt就是iShort就是sh)加上 -> 然后是函数体。

    kotlin中将高阶函数中的函数参数只有一个传参的情况简略了我们自己去写s ->的过程,直接帮我们生成了it ->,即

    fun html( a : (String) -> String){
      }
      
    html {
          s -> s + "test" 
      }
      
    //等价
    html {
       it + "test"
    }
    
  • 函数参数的自动识别

    kotlin可以自动进行推断函数体,比如,我们需要传入高阶函数的函数体是(Int) -> Int,那么如果有什么方法本身也是这种类型的,直接传入改方法即可。

    fun html( a : (String) -> String){
      }
      
      fun testString(a : String): String{
          return a
      }
    
    fun main(){
          html {
             testString("1")
          }
    }
    
  • 高阶函数没有使用到函数参数

    我们上面举的例子中都没有使用到具体的方法参数,即html中我们并没有去使用a,这样的话在编译的过程中,传入的方法将不会被编译。

    即上文中的testString方法将完全不会被编译到main方法中

    高阶函数我们一般的使用方法都是在方法中调用方法,直接调用方法的方式如下

    fun html( a : (String) -> String){
        a.invoke("hello")
        a("hello")
    } 
    

    否则高阶函数将变得没有意义。

相关文章

网友评论

    本文标题:Kotlin学习笔记之 19 高阶函数与 lambda 表达式

    本文链接:https://www.haomeiwen.com/subject/xduxwqtx.html