Scala中function的理解

在函數式語言中,函數是和value同樣地位的一等公民,他能夠做爲變量,或者做爲參數傳遞給另外一個函數數組

##做爲變量
val f=(x:Int)=>x+1
爲啥能夠這樣寫?
因爲scala是OOP,因此function也是個object。各個function都是繼承了Function類,好比Function1類表示參數是1的function類。
 
可見上述f是一個Function1的實例。因此做爲實例的f有Function1的全部方法,其中有一個是apply方法,就是當f(1)的時候就會自動調用Function1的x+1這個方法。
這個時候怎麼又來了個方法(method),函數和方法的區別是什麼?
###function 和method的區別
能夠說函數(function)是class,而method就是class中的一個函數(這個函數是指Java上的概念)。爲啥呢,上面說了,各個function都是從Function繼承過來的,那麼每一個function都有一個特定的method,這個method是啥呢,就是能體現這個function真正做用的method,好比上面的就是x+1,只不過被Function類用apply包裝了。咱們能夠 想象成:
object myFunction extends Function1(){
    ...
    apply(x:Int):Int=x+1
    ...
}
那麼val f=(x:Int)=>x+1其實就是val f=new myFunction()
因此f(1)=f.apply(1)
因此,結論就是,函數的概念是大於方法的,函數其實本質是class,他是包含了方法的。
因此在理解了Function實際上是class後,能很好的理解函數爲何能夠做爲變量了,其實f就是這個Function的一個實例而已。
###關於Function與method的轉換
method轉爲Function
定義了一個g方法,那麼如何將方法轉爲函數呢
能夠經過_來實現
val h=g _
這樣h就成了一個實例了。
>關於下劃線_的做用
  1. 做爲「通配符」,相似Java中的*。如import scala.math._
  2. :_*做爲一個總體,告訴編譯器你但願將某個參數看成參數序列處理!例如val s = sum(1 to 5:_*)就是將1 to 5看成參數序列處理。
  3. 指代一個集合中的每一個元素。例如咱們要在一個Array a中篩出偶數,並乘以2,能夠用如下辦法:a.filter(_%2==0).map(2*_)。
  又如要對緩衝數組ArrayBuffer b排序,能夠這樣:
  val bSorted = b.sorted(_
  4. 在元組中,能夠用方法_1, _2, _3訪問組員。如a._2。其中句點能夠用空格替代。 
  5. 使用模式匹配能夠用來獲取元組的組員,例如
  val (first, second, third) = t
  但若是不是全部的部件都須要,那麼能夠在不須要的部件位置上使用_。好比上一例中val (first, second, _) = t
  6. 還有一點,下劃線_表明的是某一類型的默認值。
  對於Int來講,它是0。
  對於Double來講,它是0.0
  對於引用類型,它是null。
  7.  用於將方法轉換成函數,好比val f=sqrt _,之後直接調用f(250)就能求平方根了
 
##做爲參數傳遞
定義了一個fun方法,裏面的參數有兩個一個是int型的x,一個是參數爲int,返回值是int類型的函數f(感受和C語言中的函數指針有點像)
那麼如何往裏面傳值呢,其實這裏傳的仍是一個變量,只是這個變量是Function的實例。上面分析了method能夠轉換爲Function,因此這裏至少有兩種方法。
1. 直接傳一個變量,好比val m=(x:Int)=>x+1
接着
2. 傳一個方法(固然這個方法的參數和返回值須要知足上述條件)
接着
這個能成功運行,說明這裏有一個隱性的轉換機制。
 
>=>的做用
在Function中,表示將左邊的轉爲右邊的
val triple=(x:Double)=>3*x
將函數做爲參數
def fun(f:(Double)=>Double)=f(0.25)
這裏表示fun函數接受一個f函數做爲參數,這裏的f類型是(Double)=>Double表示輸入爲Double,輸出爲Double的函數
相關文章
相關標籤/搜索