事實上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。
沒有留言:
張貼留言