Scala学习系列(七)函数式编程

说明:本文将知识点全部写在代码中,后续再拿出来总结吧

一.函数式编程

Scala关心三个点:函数,函数入口参数,函数返回结果   

主要关心解决方案

代码:

package com.zpark.bigdata.scala.chapter05

object Scala01_Function {
  def main(args: Array[String]): Unit = {
    //TODO 函数式编程

    //编程的范式(规范形式)
    //面向对象:解决问题时将问题分解成一个一个小问题(形成了对象),分别解决
    //        对象关系:继承,实现,多态,重写       TODO 主要关心他们之间的关系

    //函数式编程关心的是问题解决的方案(封装功能):重点在于函数(功能)函数入参,出参
    //      关心三个点:函数,函数入口参数,函数返回结果    TODO 主要关心解决方案

    //函数式编程重要的是函数

    //TODO Java中的方法和Scala中的函数都可以进行功能的封装,但是方法必须和类型绑定,但是函数不需要

    //声明函数
    // Java方法声明
    //public static void test (String s){ 方法体}
    //Scala函数声明
    //TODO Scala语法很灵活,在任意语法中可以声明其他语法规则
    def test(s: String):Unit={
      //函数体
      println(s)
    }

    //调用函数
    test("zhangsan")

  }
}

二.函数:入参(方法参数),出参(返回值)

代码:

package com.zpark.bigdata.scala.chapter05

object Scala02_Function01 {
  def main(args: Array[String]): Unit = {
    //函数:入参(方法参数),出参(返回值)
    //无参,无返回值
    def test():Unit={
      println("Test")
    }
    test()

    //有参,无返回值
    //TODO 函数没有重载的概念
    //TODO 如果在同一作用域中,函数不能重名
    def test1(s:String):Unit = {
      println(s)
    }
    test1("zhangsan")

    //有参,有返回值
    def test2(s:String):String = {
       return  s + "........"
    }
    val rtnVal: String = test2("lisi")
    println(rtnVal)

    //无参,有返回值
    def test3(): String ={
      return "Hello World"
    }
    println(test3())

    //Scala中没有throws关键字,所以函数中如果有异常发生,也不需要在函数声明时抛出异常

  }
}

三.函数简化过程

package com.zpark.bigdata.scala.chapter05

object Scala03_Function02 {
  def main(args: Array[String]): Unit = {
    //TODO Scala中可以采用自动推断功能来简化函数的声明
    //1.如果函数声明中,明确无返回值Unit,那么即使函数中有return也不起作用
    /*
    def test(): Unit ={
      //println("Hello World")
      return "zhangsan"
    }
    */

    //2.如果将函数体最后一行代码进行返回,那么return关键字可以省略
    /*
     def test(): String ={
       //return"zhangsan"
      "zhangsan"
    }
     */

    //3.如果可以根据函数的最后一行代码推断类型,那么函数返回值类型可以省略
    /*
    def test()={
      "zhangsan"
    }
    */

    //4.如果函数体重只有一行代码,大括号可以省略
    //def test()="zhangsan"

    //5.TODO 如果函数声明中没有参数列表,小括号可以省略
    //TODO 如果函数小括号省略,那么访问时不能加小括号
    //TODO 声明函数必须加def  def:声明函数      val:变量
    def test="zhangsan"
   // val test1="lisi"
    println(test)

    //如果明确函数没有返回值,那么等号可以省略,省略后,编译器不会将函数体最后一行代码作为返回值
    //如果函数没有参数列表,可以省略小括号,调用时一定不能使用小括号
    //如果函数没有参数列表,但是没有省略小括号,调用时可加可不加

    //扩展:匿名函数
    ()->{println("vvvvvvvvvvv")}
  }
}

四.函数式编程:扩展

1.可变参数
2.默认参数
3.带名参数

package com.zpark.bigdata.scala.chapter05

object Scala04_FunctionHard {
  def main(args: Array[String]): Unit = {
    //函数式编程:扩展
    //TODO 可变参数
    def test(name:String*): Unit ={
      println(name)
    }
    //调用函数时,可传多个参数,也可以不传参数
    //test("zhangsan","lisi","wangwu")
    //运行后结果 WrappedArray(zhangsan, lisi, wangwu)

    //test()
    //运行后结果List()

    //TODO 默认参数
    //如果希望函数中的某一个参数使用默认值,那么可以在声明时直接赋初始值
    //Int = 20 就是默认值
    def test1(name: String,age:Int = 20): Unit ={
      println(s"${name} - ${age}")
    }

    def test2(name2:String = "lisi",name1:String): Unit ={
      println(s"${name1} - ${name2}")
    }

    test1("zhangsan",22)
    //调用函数时,参数匹配规则为从前到后,从左到右
    //test2("zhangsan","wangwu")

    //TODO 带名参数
    //能明确传那个值
    test2(name1="zhangsan")
  }
}

五.函数式编程--地狱(重点)

代码主要内容:


 1.Scala是完全面向函数式编程语言

函数可以在Scala中做任何事情
函数可以赋值给变量
函数可以作为函数的参数
函数可以作为函数的返回值

2.函数柯里化

3.闭包

一个函数在实现逻辑时,将外部的变量引入到函数的内容,改变了这个变量的声明周期,称之为闭包

4.使用匿名函数改善代码

实现把一段逻辑传递给另外一个函数

 

代码练习及说明如下

package com.zpark.bigdata.scala.chapter05

object Scala05_FunctionHell {
  def main(args: Array[String]): Unit = {
    //函数式编程 - 地狱

    //TODO Scala是完全面向函数式编程语言

    //函数可以在Scala中做任何事情
    //函数可以赋值给变量
    //函数可以作为函数的参数
    //函数可以作为函数的返回值
//例一
    /*
    def f(): Unit ={
      println("function")
    }
    def f0() = {
      //返回值
      //直接返回函数,有问题,需要增加特殊符号:下划线
      f _
    }

    f0()()
     */
    //解释f0()()
//    val ff: () => Unit = f0()
//    ff()


  //例二:嵌套写法
    /*
    def f1(i:Int) ={
      def f2(j:Int): Int ={
        i * j
      }
      f2 _
    }
    println(f1(10)(2))

     */

    //TODO 函数柯里化
    /*
    def f3(i:Int)(j:Int):Int = {
      i * j

    }
    println(f3(2)(5))

     */

    //TODO 闭包
    //一个函数在实现逻辑时,将外部的变量引入到函数的内容,改变了这个变量的声明周期,称之为闭包
   /*
    def f1(i:Int) ={

      def f2(j:Int): Int ={
        i * j
      }
      f2 _
    }
   f1(10)(2)
   */

    //将函数作为参数传递给另一个函数,需要采用特殊的声明方式
    //()=>Unit
    //参数列表=>返回值类型
    /*
    def f4(f :()=>Int): Int ={
      f() + 10
    }
    def f5(): Int ={
      6
    }
    println(f4(f5))

     */

    //TODO 使用匿名函数改善代码
    //把一段逻辑传递给另外一个函数
    /*
    def f6(f:()=>Unit): Unit ={
      f()
    }
    f6(()=>(println("xxxxxxxxx")))

     */

   //例1
    /*
    def f7(f:(Int)=>Unit): Unit ={
      f(10)
    }
    def f8(i:Int): Unit ={
      println(i)
    }
    f7(f8)
*/
    //匿名函数写法
    /*
    def f7(f:(Int)=>Unit): Unit ={
      f(10)
    }
    //TODO 简化过程
    //f7((i:Int)=>{println(i)})
    //1.前面声明时已经明确了要给一个Int类型的值,所以Int可以省略
    //f7((i)=>{println(i)})
    //2.如果花括号里只有一行代码的话,花括号可以被省略
    //f7((i)=>println(i))
    //3.当参数只用到了一次,参数可以用特殊符号下划线来代替参数
    //f7(println(_))
    //4.既然只有一个参数,那么下划线也可以被省略
    f7(println)

     */

    //例2
    def f9(f:(Int,Int)=>Int): Int ={
      f(10,10)
    }

//    def f10(i:Int,j:Int): Int ={
//      i + j
//    }
//    println(f9(f10))

    //用匿名函数的方式来声明
    //TODO 简化过程
    //println(f9( (x:Int,y:Int)=>{x+y}))
    //1.前面声明时已经明确了要给一个Int类型的值,所以Int可以省略
    //println(f9( (x,y)=>{x+y}))
    //2.如果花括号里只有一行代码的话,花括号可以被省略
    //println(f9( (x,y)=>x+y))
    //3.当参数只用到了一次,参数可以用特殊符号下划线来代替参数
    println(f9(_+_))



  }
}


 

六.递归函数

package com.zpark.bigdata.scala.chapter05

object Scala06_RecursionFunction {
  def main(args: Array[String]): Unit = {
    //TODO 递归
    //1.函数的逻辑代码中调用自身
    //2.函数在调用自身时,传递的参数应该有规律
    //3.函数应该有跳出递归的逻辑,否则出现死循环
    //4.递归函数无法推断出函数的返回值类型。所以必须要声明

    //TODO 阶乘 = 一个大于1的数的阶乘 = 这个数 * (数 - 1)阶乘
    //例:5的阶乘= 5*4*3*2*1 = 120
    def !!(i:Int): Int ={
      if (i == 1){
        1
      }else{
        i * !!(i-1)
      }
    }
    //5的阶乘= 5*4*3*2*1 = 120
    println(!!(5))

  }
}

 

七.简化还原

package com.zpark.bigdata.scala.chapter05

object Scala07_RevFunction {
  def main(args: Array[String]): Unit = {
    //TODO 反转简化后的函数
    //f1是简化后的写法,f2是正常写法
    /*
    def f1 = "zpark"
    def f2(): String ={
      "zpark"
    }
    println(f1)

     */

    //function类型最大为22
    val f = () => {}
    //当前输出为<function0>  个数就算是()里参数的个数,最大为22
    println(f)
  }
}

八. 惰性函数

package com.zpark.bigdata.scala.chapter05

object Scala08_LazyFunction {
  def main(args: Array[String]): Unit = {
    //TODO 惰性函数
    /*
    1.lazy 不能修饰 var 类型的变量
    2.不但是 在调用函数时,加了 lazy ,会导致函数的执行被推迟,
    我们在声明一个变量时,如果给声明了 lazy ,那么变量值得分配也会推迟。
    比如 lazy val i = 10
     */
    lazy val res = sum(10, 20)
    println("-----------------")
    println("res=" + res)
  }
  def sum(n1 : Int, n2 : Int): Int = {
    println("sum() 执行了..")
    return  n1 + n2


}
}

九.异常处理

package com.zpark.bigdata.scala.chapter05

object Scala09_Exception {
  def main(args: Array[String]): Unit = {
    //异常
    try{
      val i = 10
      val j = 0
      val k = i/j

    }catch {
      //类似于java中switch用法
      //语法规则类似于匿名函数
      case ex:ArithmeticException =>println("捕捉了算术为0的算术异常")
      case ex:Exception =>println("捕捉了异常")

    }finally {
      println("finally......")

    }
  }
}

 

附加.工程图示

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值