1. 程式人生 > >Scala入門到精通——第五節 函式與閉包

Scala入門到精通——第五節 函式與閉包

本節主要內容

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

(二)匿名函式

(三)函式的簡化

(四)函式引數

(四)閉包

函式字面量(值函式)

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

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

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

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

scala> println(increase(10
)) 11
//前面的語句等同於
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

匿名函式

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

函式進一步簡化


//花括方式(寫法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

函式引數

//函式引數(高階函式)
//((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   

函式閉包

 //閉包(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

新增公眾微訊號,可以瞭解更多最新Spark、Scala相關技術資訊
這裡寫圖片描述