(二)Scala函數式編程

函數式編程

Scala也是一種函數式編程語言,其函數也能當成值來使用。Scala提供了輕量級的語法用以定義匿名函數,支持高階函數,容許嵌套多層函數,並支持柯里化。Scala的case class及其內置的模式匹配至關於函數式編程語言中經常使用的代數類型。python

在Scala中,存在方法和函數兩個概念,方法和函數在語義上區別很細小。
Scala 中的方法跟 Java 的相似,方法是組成類的一部分。scala 中的函數則是一個完整的對象。
Scala中方法和函數在語法上區別不大,只是類中聲明的函數咱們叫方法,方法有重載和重寫,而函數則沒有。編程

1.普通函數編程

1.1 基本語法

[修飾符] def 函數名 ( 參數列表 ) [:返回值類型] = {
    函數體
}

示例閉包

object Scala_Fun {
  def main(args: Array[String]): Unit = {
    test("hello")
  }

  /**
   * 普通函數示例
   * @param str
   */
  private def test(str:String):Unit = {
    println(str)
  }
}

1.2 函數定義

object Scala_Fun {
  def main(args: Array[String]): Unit = {
    // 無參,無返回值
    def fun1(): Unit ={
      println("無參且無返回值")
    }
    
    // 無參,有返回值
    def fun2(): String ={
      // 能夠省略return
      "張三" 
    }
    
    // 有參,無返回值
    def fun3(str:String): Unit ={
      println(str)
    }
    
    // 有參,有返回值
    def fun4(str:String): String ={
      "hello:"+ str
    }
    
    // 關鍵字參數
  }

}

1.3 函數參數

object Scala_Fun {
  def main(args: Array[String]): Unit = {
    // 可變參數
    def fun1(names:String*): Unit ={
      println(names)
    }
    fun1("張三","李四")

    // 可變參數不能放置在參數列表的前面,通常放在參數列表的最後
    // 若是學過python,會發現傳參這裏跟python傳參很類似
    /*    錯誤示範
    def fun2(names:String*, count:Int): Unit ={

    }*/
    def fun2(count:Int,names:String*): Int ={
      println(names)
      count
    }

    // 參數默認值
    def fun3(name:String, age:Int = 18): Unit ={
      println(name+ ":" + age)
    }
    
    // 命名傳參
    fun3(name="張三")

  }
  
}

1.4 函數精簡原則

object Scala_Fun {
  def main(args: Array[String]): Unit = {
    // Scala中函數能夠進行精簡,所謂是能省則省,固然前提是編譯器能夠自動推斷
    def fun1(name:String): String ={
      return "姓名:"+name
    }

    // 1.當函數有返回值時,能夠將函數體中最後一行執行的代碼做爲返回結果,因此能夠省略return關鍵字
    def fun2(name:String): String ={
      "fun2:"+name
    }
    println(fun2("張三"))

    // 2.若是編譯器能夠推斷出函數的返回值類型,返回值類型則能夠省略
    def fun3(name:String)={
      "fun3:"+name
    }
    println(fun3("張三"))

    // 3.若是函數體邏輯只有一行代碼,則函數體的大括號能夠省略
    def fun4(name:String) = "fun4:"+name
    println(fun4("張三"))

    // 4.若是函數沒有參數,調用時候,小括號能夠省略
    def fun5(): String ={
      "fun5"
    }
    println(fun5)

    // 5.若是函數沒有提供參數,那聲明時,小括號能夠省略,調用時,也不能使用小括號
    def fun6 = "fun6"
    println(fun6)

    // 6.若是函數使用Unit聲明沒有返回值,那函數體中的return關鍵字不會起做用。
  /*
    def fun7():Unit={
      return "張三"
    }*/
    // 7.函數體中若是使用return關鍵字,則返回值不能省略
    def fun8():String = {
      "fun8"
    }
    // 8.若是函數沒有返回值,Unit又不想用,那能夠同時省略等號,但保留花括號
    def fun9(){
      println("張三")
    }

    // 9.匿名函數:當只關心代碼邏輯,不關心函數名時,則函數名和def關鍵字能夠省略
    // 匿名函數規則: (參數列表) => {函數邏輯}
    val fun10 = (name:String)=>println(name)
    fun10("張三")

   }

}

2.高階函數編程

2.1什麼是高階函數和柯里化Currying

1)數學概念編程語言

回顧下數學知識:
y=f(x) 這是最開始接觸的普通函數
y=g(f(x)) 這個就是咱們接觸到的高階函數

在數學和計算機科學中,高階函數至少應當是知足下面一個條件的函數:
1)接受一個或者多個函數做爲參數
2)輸出一個函數函數式編程

程序中咱們的高階函數也相似函數

2)柯里化Currying
柯里化:指的是將原來接受兩個參數的函數變成新的接收一個參數的函數,新的函數返回一個以原有第二個參數爲參數的函數
z = f(x, y)轉換成z=f(x)(y)scala

2.2 函數做爲值

object Scala_Fun {
  def main(args: Array[String]): Unit = {
    def fun1():String = {
        "張三"
    }
    val v1 = fun1() // 調用函數,把函數的返回結果賦值給變量v1
    val v2 = fun1 _ // 把函數做爲值賦值給變量v2
    println(v1)
    println(v2)

   }

}

2.3 函數做爲參數

object Scala_Fun {
  def main(args: Array[String]): Unit = {
    def fun1():String = {
        "張三"
    }

    def fun2(fun:()=>String): Unit ={
      println(fun())
    }
    fun2(fun1)

   }

}

2.4 把函數做爲返回值

object Scala_Fun {
  def main(args: Array[String]): Unit = {
    def fun1():String = {
        "張三"
    }

    def fun2() = {
      fun1 _
    }
    println(fun2()())

   }

}

2.5 閉包

函數在使用外部變量時,若是外部變量失效時,會將這個變量包含到當前的函數內部,造成閉合的效果,這個就是閉包。
匿名函數自己就是一種閉包。
代碼示例code

object Scala_Fun {
  def main(args: Array[String]): Unit = {
    def outFun(i:Int) ={
      def inFun(j:Int) = {
        i + j
      }
      inFun _
    }
    val res = outFun(10)(10)
    println(res)
  }

}

2.6 惰性函數

惰性函數,也就是延遲加載,直到咱們首次對此取值,該函數纔會執行,使用lazy關鍵字聲明其返回值時,就會造成惰性函數。
示例:對象

object Scala_Fun {
  def main(args: Array[String]): Unit = {
    def fun():String = {
      println("張三")
      "張三"
    }
    lazy val res = fun()
    println(res)
  }

}

2.7 函數柯里化

object Scala_Fun {
  def main(args: Array[String]): Unit = {
    // 使用柯里化方式聲明函數
    def fun1(a:Int,b:Int,f:(Int,Int)=>Int):Unit = {
    }
    def fun2(a:Int)(b:Int)(f:(Int,Int)=>Int) = {
      f(a,b)
    }
    // 調用函數
    println(fun2(10)(20)(_ + _))
  }

}

學過Python的話,會發現這裏的高階函數和Python的高階函數大同小異。編譯器

相關文章
相關標籤/搜索