本節主要內容
(一)函數字面量(值函數)
(二)匿名函數
(三)函數的簡化
(四)函數參數
(四)閉包
函數字面量(值函數)
函數字面量(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