code

2016年10月27日 星期四

Scala筆記 13 - function as objects

之前說Scala中的值都可以是物件,那functions呢?

事實上scala package中有所有function的trait definition,以下是一個1-parameter的trait:



所以某個function A=>B 其實在Scala compiler看來就是extends  Function1[A,B]的object而已!目前最多支援到Function22。

我們知道anonymous function是一個function literal (或說是function value),在compiler眼中其實就是extends Function1[A,B]的trait instance:



舉例來說,以下的expression會被compiler轉譯成Function1物件:



注意f是一個function value/literal。


不過Function1中的apply method是不是會被compiler再次轉譯成Function1物件,然後無限迴圈下?!

還好不會。所有的function定義都只會在被呼叫的時候轉譯成anonymous function value,然後再被轉譯成Function1的instance。這叫eta expansion。


Every object can also act like a function

這個比較奇怪,我們可以把function看成是anonymous Function1 object(如果只有一個參數),但是我們也可以把object用function語法傳遞參數與呼叫:


object Test {
  def apply(x:Int): Int = 0  def apply(): Int = 1}

Test(1) //returns 0
Test()  //returns 1


看網路上說明,這個通常是用來作為factory pattern用的,例如在某個collection class/object 中implement apply method,就可以製作不同configuration的instance,例如:





總之 f(..) 在scala中應該是一個syntatic sugar而已,實際運作上還是要實體化一個object,然後呼叫其對應的apply method。



沒有留言:

張貼留言