• Spark基础-scala学习(四、函数式编程)


    函数式编程

    1. 将函数赋值给变量
    2. 匿名函数
    3. 高阶函数
    4. 高级函数的类型推断
    5. scala的常用高阶函数
    6. 闭包
    7. sam转换
    8. currying函数
    9. return

    将函数赋值给变量

    1. scala中的函数是一等公民,可以独立定义,独立存在,而且可以直接将函数作为值赋值给变量
    scala> def sayHello(name:String){println("Hello, "+name)}
    sayHello: (name: String)Unit
    
    scala> sayHello("tom")
    Hello, tom
    
    scala> val sayHelloFunc = sayHello _
    sayHelloFunc: String => Unit = $$Lambda$1061/1964697764@235d659c
    
    scala> sayHelloFunc("leo")
    Hello, leo
    

    匿名函数

    1. scala中,函数也可以不需要命名,此时函数被称为匿名函数
    2. 可以直接定义函数后,将函数赋值给某个变量;也可以将直接定义的匿名函数传入其他函数之中
    3. scala定义匿名函数的语法规则就是,(参数名:参数类型)=>函数体
    scala> val sayHelloFunc = (name:String) => println("hello, "+name)
    sayHelloFunc: String => Unit = $$Lambda$1070/547507935@29962b2f
    
    scala> sayHelloFunc("leo")
    hello, leo
    
    

    高阶函数

    1. scala中函数时一等公民,因此可以直接将某个函数传入其他函数,作为参数。这个功能是及其强大的,也是java这种面向对象的编程语言所不具备的
    2. 接收其他函数作为参数的函数,也被称为高阶函数(higher-order function)
    scala> val sayHelloFunc = (name:String)=>println("Hello, "+name)
    sayHelloFunc: String => Unit = $$Lambda$1167/1510403823@1c0cf193
    
    scala> def greeting(func:(String)=> Unit,name:String){func(name)}
    greeting: (func: String => Unit, name: String)Unit
    
    scala> greeting(sayHelloFunc,"leo")
    Hello, leo
    
    scala> Array(1,2,3,4,5).map((num:Int)=>num*num)
    res5: Array[Int] = Array(1, 4, 9, 16, 25)
    
    1. 高阶函数的另外一个功能是将函数作为返回值
    scala> def getGreetingFunc(msg:String)=(name:String)=>println(msg+","+name)
    getGreetingFunc: (msg: String)String => Unit
    
    scala> val greetingFunc = getGreetingFunc("hello")
    greetingFunc: String => Unit = $$Lambda$1292/1385099824@ae85aad
    
    scala> greetingFunc("leo")
    hello,leo
    

    高阶函数的类型推断

    1. 高阶函数可以自动判断出参数类型,而不需要写明类型;而且对于只有一个参数的函数,还可以省去其小括号;如果仅有的一个参数在右侧的函数体内只使用一次,则还可以将接收参数省略,并且将参数用_来替代
    scala> def greeting(func:(String)=>Unit,name:String){func(name)}
    greeting: (func: String => Unit, name: String)Unit
    
    scala> greeting((name:String)=>println("Hello, "+name),"leo")
    Hello, leo
    
    scala> greeting((name)=>println("Hello, "+name),"leo")
    Hello, leo
    
    scala> greeting(name => println("Hello, "+name),"leo")
    Hello, leo
    
    scala> def triple(func:(Int)=>Int) = {func(3)}
    triple: (func: Int => Int)Int
    
    scala> triple(3* _)
    res10: Int = 9
    
    scala> triple(2+_)
    res11: Int = 5
    

    scala的常用高阶函数

    scala> Array(1,2,3,4,5).map(2* _)
    res13: Array[Int] = Array(2, 4, 6, 8, 10)
    
    scala> (1 to 9).map("*"*_).foreach(println _)
    *
    **
    ***
    ****
    *****
    ******
    *******
    ********
    *********
    
    scala> (1 to 20).filter(_ % 2 == 0)
    res16: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
    
    //从左侧元素开始,进行reduce操作,即先对元素1和元素2进行处理,然后将结果与元素3处理,再将结果与元素4处理,依次类推,即为reduce
    // 1*2*3*4*5*6*7*8*9
    scala> (1 to 9).reduceLeft(_*_)
    res17: Int = 362880
    
    //sortWith:对元素进行两两相比,进行排序
    scala> Array(3,2,5,4,10,1).sortWith(_ < _)
    res19: Array[Int] = Array(1, 2, 3, 4, 5, 10)
    

    闭包

    1. 闭包最简洁的解释,函数在变量不处于其有效作用域时,还能够对变量进行访问,即为闭包
    scala> def getGreetingFunc(msg:String) = (name:String)=>println(msg+","+name)
    getGreetingFunc: (msg: String)String => Unit
    
    scala> val greetingFuncHello = getGreetingFunc("hello")
    greetingFuncHello: String => Unit = $$Lambda$1377/116345573@1f238bc9
    
    scala> val greetingFuncHi = getGreetingFunc("hi")
    greetingFuncHi: String => Unit = $$Lambda$1377/116345573@3f33316e
    
    scala> greetingFuncHello("leo")
    hello,leo
    
    scala> greetingFuncHi("leo")
    hi,leo
    
    1. 两次调用getGreetingFunc函数,传入不同的msg,并创建不同的函数返回
    2. 然而,msg只是一个局部变量,却在getGreetingFunc执行完之后,还可以继续存在创建的函数之中,greetingFuncHello("leo")调用时,值为"hello"的msg被保留在了函数体内部,可以反复的使用
    3. 这种变量超出了其作用域,还可以使用的情况,即为闭包
    4. scala通过为每个函数创建对象来实现闭包,实际上对于getGreetingFunc函数创建的函数,msg是作为函数对象的变量存在的,因此每个函数才可以拥有不同的msg
    5. scala编译器会确保上述闭包机制

    SAM转换

    1. 在java中,不支持直接将函数传入一个方法作为参数,通常来说,唯一的办法就是定义一个实现了某个接口的类的实例对象,该对象只有一个方法;而这些接口都只有单个的抽象方法,也就是single abstract method,简称SAM
    2. 由于scala是可以调用java的代码的,因此当我们调用java的某个方法时,可能就不得不创建SAM传递给方法,非常麻烦;但是scala又是支持直接传递函数的。此时就可以使用scala提供的,在调用java方法时,使用的功能,SAM转换,即将SAM转换为scala函数
    3. 要使用SAM转换,需要使用scala提供的特性,隐式转换
    scala> import javax.swing._
    import javax.swing._
    
    scala> import java.awt.event._
    import java.awt.event._
    
    scala> val button = new JButton("Click")
    
    scala> button.addActionListener(new ActionListener{
         | override def actionPerformed(event:ActionEvent){
         |  println("Click Me!!")
         | }
         | })
    //隐式转换
    scala> implicit def getActionListener(actionProcessFunc:(ActionEvent)=>Unit)=new ActionListener{
         |  override def actionPerformed(event:ActionEvent){
         |   actionProcessFunc(event)
         |  }
         | }
         
    scala> button.addActionListener((event:ActionEvent)=>println("Click Me!!!"))
    

    Currying函数

    1. Curring函数,指的是,将原来接收两个参数的一个函数,转换为两个函数,第一个函数接收原先的第一个参数,然后返回接收原来第二个参数的第二个函数
    2. 在函数调用的过程中,就变为了两个函数去连续调用的形式
    scala> def sum(a:Int,b:Int) = a+b
    sum: (a: Int, b: Int)Int
    
    scala> sum(1,2)
    res24: Int = 3
    
    scala> def sum2(a:Int) = (b:Int)=>a+b
    sum2: (a: Int)Int => Int
    
    scala> sum2(1)(2)
    res25: Int = 3
    
    scala> def sum3(a:Int)(b:Int) = a+b
    sum3: (a: Int)(b: Int)Int
    
    scala> sum3(1)(2)
    res26: Int = 3
    

    return

    1. scala中,不需要使用return来返回函数的值,函数最后一行语句的值,就是函数的返回值。在scala中,return用于在匿名函数中返回值给包含匿名函数的带名函数,并作为带名函数的返回值
    2. 使用return的匿名函数,是必须给出返回类型的,否则无法通过编译
    scala> :paste
    // Entering paste mode (ctrl-D to finish)
    
    def greeting(name:String)={
     def sayHello(name:String):String={
      return "Hello, "+name
     }
     sayHello(name)
    }
    
    // Exiting paste mode, now interpreting.
    
    greeting: (name: String)String
    
    scala> greeting("leo")
    res27: String = Hello, leo
    
  • 相关阅读:
    CSS3新特性
    CSS简述
    HTML5新属性
    Python学习笔记(十二)
    Python学习笔记(十一)
    Python学习笔记(十)
    Python学习笔记(九)
    Python学习笔记(八)
    Python学习笔记(七)
    Python学习笔记(六)
  • 原文地址:https://www.cnblogs.com/sky-chen/p/10105445.html
Copyright © 2020-2023  润新知