第五節 函數與閉包

本節主要內容

(一)函數字面量(值函數)

(二)匿名函數

(三)函數的簡化

(四)函數參數

(四)閉包

函數字面量(值函數)

函數字面量(function literal),也稱值函數(function values),指的是函數可以賦值給變量。

一般函數具有如下形式: 
這裏寫圖片描述

而函數字面量具有如下形式:

/*
   函數字面量 function literal
   =>左側的表示輸入,右側表示轉換操作
*/
scala> val increase=(x:Int)=>x+1
increase: Int => Int = <function1>

scala> println(increase(10))
11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
//前面的語句等同於
scala>  def increaseAnother(x:Int)=x+1
increaseAnother: (x: Int)Int

scala> println(increaseAnother(10))
11

    //多個語句則使用{}
val increase2=(x:Int)=>{
      println("Xue")
      println("Tu")
      println("Wu")
      println("You")
      x+1
}
scala>println(increase2(10))
Xue
Tu
Wu
You
11


//數組的map方法中調用(寫法1)
scala> println(Array(1,2,3,4).map(increase).mkString(","))
2,3,4,5
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

匿名函數

//匿名函數寫法(寫法2)
scala>println(Array(1,2,3,4).map((x:Int)=>x+1).mkString(","))
2,3,4,5
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

函數進一步簡化


//花括方式(寫法3)
scala> Array(1,2,3,4).map{(x:Int)=>x+1}.mkString(",")
res25: String = 2,3,4,5

//省略.的方式(寫法4)
scala> Array(1,2,3,4) map{(x:Int)=>x+1} mkString(",")
res26: String = 2,3,4,5


//參數類型推斷寫法(寫法5)
scala> Array(1,2,3,4) map{(x)=>x+1} mkString(",")
res27: String = 2,3,4,5

//函數只有一個參數的話,可以省略()(寫法6)
scala> Array(1,2,3,4) map{x=>x+1} mkString(",")
res28: String = 2,3,4,5

//如果參數右邊只出現一次,則可以進一步簡化(寫法7)
scala> Array(1,2,3,4) map{_+1} mkString(",")
res29: String = 2,3,4,5


 //值函數簡化方式
 //val fun0=1+_,該定義方式不合法,因爲無法進行類型推斷
scala> val fun0=1+_
<console>:10: error: missing parameter type for expanded function ((x$1) => 1
x$1))

//值函數簡化方式(正確方式)    
scala>  val fun1=1+(_:Double)
un1: Double => Double = <function1>

scala> fun1(999)
es30: Double = 1000.0

//值函數簡化方式(正確方式2)  
scala> val fun2:(Double)=>Double=1+_
fun2: Double => Double = <function1>

scala> fun2(200)
res31: Double = 201.0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

函數參數

//函數參數(高階函數)
//((Int)=>String)=>String
scala> def convertIntToString(f:(Int)=>String)=f(4)
convertIntToString: (f: Int => String)String

scala> convertIntToString((x:Int)=>x+" s")
res32: String = 4 s

//高階函數可以產生新的函數
//(Double)=>((Double)=>Double)
scala>  def multiplyBy(factor:Double)=(x:Double)=>factor*x
multiplyBy: (factor: Double)Double => Double

scala> val x=multiplyBy(10)
x: Double => Double = <function1>

scala> x(50)
res33: Double = 500.0   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

函數閉包

 //閉包(Closure)

//(x:Int)=>x+more,這裏面的more是一個自由變量(Free Variable),more是一個沒有給定含義的不定變量
//而x則的類型確定、值在函數調用的時候被賦值,稱這種變量爲綁定變量(Bound Variable)
scala> (x:Int)=>x+more
<console>:8: error: not found: value more
              (x:Int)=>x+more
                         ^
scala> var more=1
more: Int = 1

scala>val fun=(x:Int)=>x+more
fun: Int => Int = <function1>

scala> fun(10)
res1: Int = 11

scala> more=10
more: Int = 10

scala> fun(10)
res2: Int = 20

 //像這種運行時確定more類型及值的函數稱爲閉包,more是個自由變量,在運行時其值和類型得以確定
 //這是一個由開放(free)到封閉的過程,因此稱爲閉包

scala> val someNumbers = List(-11, -10, -5, 0, 5, 10)
someNumbers: List[Int] = List(-11, -10, -5, 0, 5, 10)

scala>  var sum = 0
sum: Int = 0

scala>  someNumbers.foreach(sum += _)

scala> sum
res8: Int = -11

scala>  someNumbers.foreach(sum += _)

scala> sum
res10: Int = -22

//下列函數也是一種閉包,因爲在運行時其值才得以確定
def multiplyBy(factor:Double)=(x:Double)=>factor*x
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章