美文网首页
Lambda表达式

Lambda表达式

作者: 没有故事的男童鞋 | 来源:发表于2020-05-15 10:04 被阅读0次

    Kotlin高阶函数--Higher-Order Function

    参数或者返回值为函数类型的函数,在Kotlin中被称为高阶函数。

    高阶函数概念源自数学中的高阶函数-在数学中,如果一个函数使用函数作为他的参数或者结果,则他被称为高阶函数。

    Java中函数的参数不能是函数

    Kotlin中函数可以含有函数类型的参数,且函数的返回值也可以是函数类型

    SAM接口--Single Abstract Method

    只有一个抽象方法的接口简称SAM接口

    函数类型的参数示例

    • 无参数无返回值:(()->Unit)

    • 单Int型参数返回:String(Int->String)

    双冒号::method是什么?(函数引用Function Reference)

    ::method这种写法叫做函数引用;(method在加上::就变成了一个和函数具有相同功能的对象了)

    • 对于一个已经声明好的函数,不管是要把它作为参数传递给函数,还是把它赋值给变量,都需要在函数名的左边加上双冒号

      a(::b)
      val d = ::b
      
    • 在Kotlin中,一个函数名的左边加上双冒号,它就不表示这个函数本身了,而是表示一个对象,或者是一个指向对象的引用,但是这个对象并不是函数本身,而是和函数具有相同功能的对象

      b(1) // 调用函数
      d(1) // 用对象 a 后面加上括号来实现 b() 的等价操作
      (::b)(1) // 用对象 :b 后面加上括号来实现 b() 的等价操作
      
    • 函数类型的对象和普通对象的区别:

      普通类型的对象无法通过对象()这种方法来调用,但是函数类型的对象是可以的,但是这其实是个假的调用,它是Kotlin的语法糖。

      对一个函数类型的对象加括号,加参数,真正调用的是这个对象的invoke()函数

      d(1) // 实际上会调用 d.invoke(1)
      (::b)(1) // 实际上会调用 (::b).invoke(1)
      
      //错误写法,对一个函数调用invoke
      b.invoke(1)
      
    • 双冒号加函数名是一个指向对象的引用,但是并不是指向函数本身。而是指向一个看不见的对象,这个对象复制了原函数的功能,但它并不是原函数

    Kotlin中的匿名函数(其实是一个对象,并不是一个函数)

    简单来说就是没有名字的函数,本质是一个对象

    a(fun(param: Int): String {
        return param.toString()
    });
    val d = fun(param: Int): String {
        return param.toString()
    }
    //错误写法,左右两边都有名字,Kotlin是不允许的
    val d = fun a(param:Int):String{
        
    }
    

    Java中和Kotlin中接口回调设计及使用对比

    • Java

      //定义
      public interface OnClickListener {
        void onClick(View v);
      }
      public void setOnClickListener(OnClickListener listener) {
        this.listener = listener;
      }
      //使用
      view.setOnClickListener(new OnClickListener() {
        @Override
        void onClick(View v) {
          switchToNextPage();
        }
      });
      
    • Kotlin

      //定义
      public interface OnClickListener {
        void onClick(View v);
      }
      fun setOnClickListener(onClick: (View) -> Unit) {
        this.onClick = onClick
      }
      //使用
      view.setOnClickListener(fun(v: View): Unit) {
        switchToNextPage()
      })
      //使用lambda替换
      view.setOnClickListener({ v: View ->
        switchToNextPage()
      })
      

    Lambda表达式

    • Lambda表达式示例:

      (parameters) -> expression
      或
      (parameters) ->{ statements; }
      
      // 1. 不需要参数,返回值为 5  
      () -> 5  
      
      // 2. 接收一个参数(数字类型),返回其2倍的值  
      x -> 2 * x  
      
      // 3. 接受2个参数(数字),并返回他们的差值  
      (x, y) -> x – y  
      
      // 4. 接收2个int型整数,返回他们的和  
      (int x, int y) -> x + y  
      
      // 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)  
      (String s) -> System.out.print(s)
      
    • 当Lambda是函数的最后一个参数,或唯一参数,或单参数时的不同写法

      //Lambda是函数的最后一个参数,可以把Lambda写在括号外面
      view.setOnClickListener() { v: View ->
        switchToNextPage()
      }
      //Lambda是函数的唯一参数,直接将()去掉
      view.setOnClickListener { v: View ->
        switchToNextPage()
      }
      //如果Lambda中函数时单参数的,参数也可以省略不写
      view.setOnClickListener {
        switchToNextPage()
      }
      //如果Lambda中函数时多个参数,但是部分参数不需要使用时
      mAdapter.setOnItemClickListener { _, _, position ->
        SocietyHomeAct.toSocietyHome(this, (mAdapter.getItem(position)))
      }
      
    • Kotlin对于省略的唯一参数有默认名字:it

    • Lamda的返回值不是用return返回,而是直接取最后一行代码的值

    • 将匿名函数赋值给变量而不是作为函数参数传递的时候的写法

      val b = fun(param: Int): String {
        return param.toString()
      }
      //简写成Lambda
      val b = { param: Int ->
        return param.toString()
      }
      //错误写法
      val b = {
        return it.toString() // it 报错,因为无法根据上下文推断对象
      }
      //替代方案:给左边的变量指明类型
      val b: (Int) -> String = {
        //错误写法:Lambda的返回值不能用return返回,会直接取最后一行作为返回值
        //return it.toString() // it 可以被推断出是 Int 类型
        it.toString() // it 可以被推断出是 Int 类型
      }
      

    Kotlin里的函数和匿名函数以及Lambda表达式的本质

    它们都是函数类型的对象

    • 函数:用来实现特定功能的代码块

    • 匿名函数:不是一个函数,是一个具备与函数功能相同的对象

    • Lambda:不是一个函数,是一个函数类型的对象

    • 使用时能怎么使用双冒号加函数名就能怎么使用匿名函数,以及怎么使用Lambda表达式。

    Kotlin中的Lambda和Java8的Lambda区别

    Java从8开始引入了Lambda支持,主要作用是对于单抽象方法的接口,Java 8允许你用Lambda表达式来创建匿名类对象,但是它本质上还是创建了一个匿名类对象,只不过是一种简化的写法。

    Kotlin中的Lambda是实实在在的函数类型的对象,功能更强,写法更多更灵活,

    • Kotlin中的Lambda是函数类型的对象
    • Java 8中的Lambda只是一种便捷的写法,在功能上没有突破

    总结

    • 1、在Kotlin中,有一类Java不存在的类型,叫函数类型,这类对象可以当函数来使用的同时,还可以作为函数的参数,函数的返回值,以及赋值给变量

    • 2、创建一个函数类型的对象的三种方式

      ::b//双冒号加函数名
      val b = fun(){}//匿名函数
      val c = {}//Lambda
      
    • 3、双冒号加函数名、匿名函数和Lambda本质都是函数类型的对象;在Kotlin中,匿名函数不是函数,Lambda也只是代码块,Kotlin的Lambda可以归为函数类型的对象。

    相关文章

      网友评论

          本文标题:Lambda表达式

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