0
点赞
收藏
分享

微信扫一扫

Scala系列之:函数高级



Scala系列之:函数高级

  • 一、匿名函数
  • 二、函数高级用法
  • 三、函数高级应用案例
  • 四、函数柯里化和闭包
  • 五、传值参数和传名参数
  • 六、惰性加载


一、匿名函数

  • 没有名字的函数就是匿名函数
  • (x:Int)=>{函数体}
  • x:表示输入参数类型
  • Int:表示输入参数类型
  • 函数体:表示具体代码逻辑

匿名函数的至简原则

object LambdaTest {
  def main(args: Array[String]): Unit = {
    val fun = (name: String) => {println(name)}
    fun("篮球")



    //匿名函数作为参数
    def f(func: String => Unit): Unit = {
      func("足球")
    }

    f(fun)
    println("--------")
    f((name: String) => {println(name)})
  }
}

匿名函数的至简原则

  1. 参数的类型可以省略,会根据形参进行自动推导
  2. 类型省略后,发现只有一个参数,则圆括号可以省略。其他情况,没有参数和参数超过1的永远不能省略圆括号。
  3. 匿名函数如果只有一行,则大括号也可以省略
  4. 如果参数只出现一次,则参数省略且后面参数可以用_代替。
  5. 如果可以推断出,当前传入的println是一个函数体,而不是调用语句,可以直接省略下划线

object LambdaTest {
  def main(args: Array[String]): Unit = {
    val fun = (name: String) => {println(name)}
    fun("篮球")



    //匿名函数作为参数
    def f(func: String => Unit): Unit = {
      func("足球")
    }

    f(fun)
    println("--------")
    f((name: String) => {println(name)})

    //1。参数的类型可以省略,会根据形参进行自动推导
    f((name) => {println(name)})


    //2。类型省略后,发现只有一个参数,则圆括号可以省略。其他情况,没有参数和参数超过1的永远不能省略圆括号。
    f(name => {println(name)})

    //3。匿名函数如果只有一行,则大括号也可以省略
    f(name => println(name))

    //4. 如果参数只出现一次,则参数省略且后面参数可以用_代替。
    f(println(_))

    //5.如果可以推断出,当前传入的println是一个函数体,而不是调用语句,可以直接省略下划线
    f(println)
  }

}

二元函数使用示例:

object LambdaTest {
  def main(args: Array[String]): Unit = {

  println("-----------------")
  //定义一个二元运算函数,只操作1和2两个数,具体运算通过参数传入
  def dualFunctionOneAndTwo(fun:(Int,Int)=>Int): Int = {
    fun(1,2)
  }

  val add = (a:Int,b:Int) => a + b
  val minus = (a:Int,b:Int) => a - b
  println(dualFunctionOneAndTwo(add))
  println(dualFunctionOneAndTwo(minus))

  //二元函数简化
  println("-------------二元函数简化----------")
  println(dualFunctionOneAndTwo(_ + _))
  println(dualFunctionOneAndTwo(_ - _))
  println(dualFunctionOneAndTwo(-_ + _))

}}

输出如下所示:

-----------------
3
-1
-------------二元函数简化----------
3
-1
1

二、函数高级用法

  1. 函数作为值进行传递
  2. 函数作为参数进行传递
  3. 函数作为函数的返回值返回

object function3 {
  def main(args: Array[String]): Unit = {
    def f(n: Int): Int = {
      println("f调用")
      n + 1
    }

    val result: Int = f(123)
    println(result)

    //1.函数作为值进行传递
    val f1: Int=>Int = f
    val f2 = f _
    println(f1)
    println(f1(12))
    println(f2)
    println(f2(35))

    //2.函数作为参数进行传递
    def dualEval(op: (Int,Int)=>Int,a: Int,b: Int): Int ={
      op(a,b)
    }

    def add(a: Int,b: Int): Int = {
      a + b
    }

    println(dualEval(add,12,35))
    println(dualEval((a,b) => a + b,12,35))
    println(dualEval(_+_,12,35))

    //3.函数作为函数的返回值返回
    def f5(): Int=>Unit = {
      def f6(a: Int): Unit = {
        println("f6调用 "+ a)
      }
      f6 //将函数直接返回
    }

    val f6 = f5()
    println(f6)
    println("------------")
    println(f6(25))
  }
}

三、函数高级应用案例

应用案例一:

object function3 {
  def main(args: Array[String]): Unit = {
    val arr: Array[Int] = Array(12,45,75,98)
    //对数组进行处理,将操作抽象出来,处理完毕之后的结果返回一个新的数组
    def arrayOperation(array: Array[Int],op: Int=>Int): Array[Int] = {
      for( elem <- array) yield op(elem)
    }
    //定义一个加1操作
    def addOne(elem: Int): Int = {
      elem + 1
    }

    //调用函数
    val newArray: Array[Int] = arrayOperation(arr,addOne)
    println(newArray.mkString(","))

    //传入匿名函数,实现元素翻倍
    val newArray2 = arrayOperation(arr, _ * 2)
    println(newArray2.mkString(", "))

  }
}

四、函数柯里化和闭包

  • 闭包:函数式编程的标配
  • 闭包:如果一个函数,访问到了它的外部(局部)变量的值,那么这个函数和他所处的环境,称为闭包。

object function4 {
  def main(args: Array[String]): Unit = {

    def addByA(a: Int): Int =>Int = {
      def addB(b: Int): Int = {
        a + b
      }
      addB
    }

    println(addByA(35)(24))

    def addByA2(a: Int): Int=>Int = a + _

    println(addByA2(3)(4))
  }
}

  • 函数柯里化:把一个参数列表的多个参数,变成多个参数列表。

object function4 {
  def main(args: Array[String]): Unit = {

    def addByA(a: Int): Int =>Int = {
      def addB(b: Int): Int = {
        a + b
      }
      addB
    }

    println(addByA(35)(24))

    def addByA2(a: Int): Int=>Int = a + _

    println(addByA2(3)(4))

    def addCurrying(a: Int)(b: Int): Int = {
      a + b
    }

    println(addCurrying(2)(3))
  }

}

五、传值参数和传名参数

object function5 {
  def main(args: Array[String]): Unit = {

    //1.传值参数
    def f0(a: Int): Unit = {
      println("a " + a)
      println("a " + a)
    }

    f0(23)

    def f1(): Int = {
      println("f1调用")
      12
    }
    f0(f1)

    println("---------------------------")
    //2.传名参数,传递的不再是具体的值,而是代码块
    def f2(a: =>Int): Unit = {
      println("a: " + a)
      println("a: " + a)
    }

    f2(23)
    f2(f1())

  }

}

输出如下所示:

a 23
a 23
f1调用
a 12
a 12
---------------------------
a: 23
a: 23
f1调用
a: 12
f1调用
a: 12

六、惰性加载

  • 当函数返回值被声明为lazy时,函数的执行将被推迟,直到首次对此取值,该函数才会执行。这种函数称之为惰性函数。

object function5 {
  def main(args: Array[String]): Unit = {

    lazy val result: Int = sum(13,47)

    println("1.函数调用")
    println("2.result = " + result)
    println("4.result = " + result)
  }

  def sum(a: Int, b: Int): Int = {
    println("3.sum调用")
    60
  }

}

输出如下所示:

1.函数调用
3.sum调用
2.result = 60
4.result = 60


举报

相关推荐

0 条评论