Scala基础知识笔记3-函数

 

object ScalaFunction {

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

    // 1 将函数赋值给变量时,  必须在函数后面增加 空格和下划线
    var zmHello = sayHello _
    zmHello("zm") // 使用变量调用函数

    /**
      *  2 匿名函数
      *  2.1 将匿名函数赋值给变量  (参数名: 参数类型) => 函数体
      *  2.2 将匿名函数传入其他函数中
      *
       */
   var saySome =  (name:String) => {println("hello niming " + name)} //  实现 2.1的效果
    saySome("zm")

    /**
      * 功能1: 调用高阶函数
      * 高阶函数 : 接收其他函数作为参数的函数
      * 参数1表示接收的是一个函数,函数参数是string类型,返回值是Unit
      * 参数2表示参数是string类型
      * 函数体是调用参数1的函数,同时参数1的函数的参数是高级函数参数2
      */
      def higherOrderFun(func:String =>Unit,name:String) {
        func(name)
      }
     higherOrderFun(saySome,"higher fun zm") // hello niming higher fun zm

    var saySome1 = (name:String,age:Int) => {println("higher fun1: hello: " + name +  " the age is "  + age )} // 定义普通函数
    def higherOrderFun1(func:(String,Int)=>Unit,name:String,age:Int): Unit = { // 定义高阶函数
      func(name,age)
    }
    higherOrderFun1(saySome1,"zm",39) // 调用高阶函数



    // 高阶函数功能2  将函数作为返回值
    // 匿名函数作为返回值赋值给另一个函数
    def highOrderFun2(msg:String) = (name:String) => {println(msg + " : "+ name)}  //
    var doSome = highOrderFun2("highOrderFun2") // doSome = { (name:String) => {println(highOrderFun2 + ":" + name)} }
    doSome("zm") // doSome("zm") = { (name:String) => {println(highOrderFun2 + ":" + zm)} } ----》 结果就是   highOrderFun2 : zm
    doSome("liang")

    /**
      * 高阶函数的类型推断
      * 1 可以自动推断参数类型,可以不写参数类型
      * 2 对于只有一个参数的 可以省略参数的小括号
      * 3 如果只有一个参数且函数体内只使用一次则在函数体内 形参可用 _ 替代
      * 4 在spark源码中经常使用到
      */
      def greeting(func:(String)=>Unit,name:String) {func(name)} // 定义高级函数
      greeting((name:String)=>{println("hello  " + name)},"leo")  // 调用
      greeting(name=>println("hello1 " + name),"leo")//  参数类型可以不写 形参小括号可以不带

      def triple(func:(Int) => Int ) {func(3)}  // 形参是一个 可以将形参名也去掉
      println(triple(4 * _)) // 4 * _ 作为一个操作当成一个整个给了形参  func:(Int) => Int , 函数体是 {func(3)}  其中 在定义函数func时 因为只有一个参数且在函数体只用了一次因此这个形参用_表示
     // 而函数体 {func(3)}中 给这个唯一使用的形参赋值为3 因此针对操作 4 * _ ,在函数体{func(3)}  针对形参进行了赋值 就变成了  4 * 3 = 12
    /**
      * 在执行 triple(4 * _) 时,  4*_ 这个操作 等同于 func:(Int) => Int   triple函数的函数体是  func(3)   其中操作 4*_中的_表示函数func中的参数因为只有一个切在函数体内只用到一次因此用_
      * 而函数体 func(3)就是给这个形参赋值  因此操作  4*_ 就是 4*3 = 12
      */

    /**
      * scala中的高级函数
      *
      */

    var newArray = Array(1,2,3,4).map((num:Int) => {num * num}) // 数组array中使用匿名函数案例
    println(newArray.mkString(",")) // 1,4,9,16

    // 数组使用map方法对每个元素映射
    Array(1,2,3,4,5).map(2*_)
    Array(1,2,3,4).map((num:Int)=>{num * num})

    var newArray1 = Array(1,2,3,5,6,7).map(2*_)
    println(newArray1.mkString(","))
    // 序列使用 map方法
   var c =  (1 to 5).map(2*_)
    println( c.mkString("-"))

    // foreach方法
    (1 to 5).map(3+_).foreach(println _ )
    Array(1,2,3,4,5).map(2 + _).foreach(println _ )

    // filter方法
    (1 to 5).filter(_%2 == 0).foreach(println(_))
    Array(1,2,3,4,5).filter(_%2!=0).foreach(println(_))

    // reduceLeft 从左侧元素开始,进行reduce操作,即先对元素1和元素2进行处理,然后将结果与元素3处理,再将结果与元素4处理,依次类推
    var resu = (1 to 3).reduceLeft(_ + _)
    println(resu)
    println(Array(1,2,3,4).reduceLeft(_+_))

    // sortWith  对元素进行两两相比,进行排序
    var  newArr = Array(11,2,13,4).sortWith(_<_)
    println(newArr.mkString("-")) // 2-4-11-13

    /**
      * 闭包
      * 函数在变量不处于其有效作用范围时,还能够对变量进行访问
      * 其中 msg参数定义在 匿名函数 (name:String) =>{println(msg + " , " + name)} 之外
      * 但是匿名函数又能够访问到msg的值 这就是闭包
      * 能够访问到的原理: Scala为每个函数创建对象来实现闭包  我理解就是 saySomething("nihao ") 创建对象1, 对象1里的参数msg = nihao 同理对象2里的msg = hello 这样这两个函数|对象就有了不同的msg值
      * Scala编译器会确保上述闭包机制
      */
    def saySomething(msg : String) = (name:String) =>{println(msg + " , " + name)}
    var some1 = saySomething("nihao ")
    var some2 = saySomething("hello ")

    println(some1("zm")) // nihao  , zm
    println(some2("zm")) // hello  , zm

    /**
      * SAM转换
      */

    /**
      * Currying函数
      * 将原来接收两个参数的函数,转换为两个函数
      * 现象: 两个函数连续调用
      */
    def sum(a:Int,b:Int) =  a + b
    println(sum(1,20))

   def sum2(a:Int) = (b:Int) => a+b
    println(sum2(1)(20))

    def sum3(a:Int)(b:Int) = a + b
    println(sum3(1)(20))



  }

  def sayHello(name:String) {println("hello " + name)}
}

 

posted on 2019-06-06 17:40  ligongda2006  阅读(157)  评论(0编辑  收藏  举报