古詩詞大全網 - 個性簽名 - scala中方法和函數的區別

scala中方法和函數的區別

Scala中既有函數也有方法,大多數情況下我們都可以不去理會他們之間的區別。但是有時候我們必須要了解他們之間的不同。

Scala中的方法跟Java的方法壹樣,方法是組成類的壹部分。方法有名字、類型簽名,有時方法上還有註解,以及方法的功能

實現代碼(字節碼)。

Scala中的函數是壹個完整的對象。Scala中用22個特質(trait)抽象出了函數的概念。這22特質從Function1到Function22

如上圖中的Function10代表的是:有10個形參,返回值為R(協變)的函數。

Scala中的函數其實就是繼承了這些Trait的類的對象,如:我們通過函數字面量定義壹個函數

其實上述函數的定義方式跟如下定義方式等同:

由於Function2是特質,不能直接new。上述new Function2[Int,Int,Int](){}其實是定義並實例化壹個實現了Function2特質的類的對象。

apply是scala中的語法糖:對壹個對象obj上調用obj(),scala編譯器會轉換為obj.apply();在壹個類clazz上調用clazz(),scala編譯器會轉

換為clazz_company_obj.apply(),其中clazz_company_obj為clazz的伴生對象。

具體的差異,總結為如下幾點:

1.方法不能作為單獨的表達式而存在(參數為空的方法除外),而函數可以。如:

在如上的例子中,我們首先定義了壹個方法m,接著有定義了壹個函數f。接著我們把函數名(函數值)當作最終表達式來用,由於f本身就是

壹個對象(實現了FunctionN特質的對象),所以這種使用方式是完全正確的。但是我們把方法名當成最終表達式來使用的話,就會出錯。

2.函數必須要有參數列表,而方法可以沒有參數列表

在如上的例子中,m1方法接受零個參數,所以可以省略參數列表。而函數不能省略參數列表

3.方法名是方法條用,而函數名只是代表函數對象本身

這個比較容易理解。因為保存函數字面量的變量(又稱為函數名或者函數值)本身就是實現了FunctionN特質的類的對象,要調用對象的apply

方法,就需要使用obj()的語法。所以函數名後面加括號才是調用函數。如下:

4.在需要函數的地方,如果傳遞壹個方法,會自動進行ETA展開(把方法轉換為函數)

如果我們直接把壹個方法賦值給變量會報錯。如果我們指定變量的類型就是函數,那麽就可以通過編譯,如下:

當然我們也可以強制把壹個方法轉換給函數,這就用到了scala中的部分應用函數:

5.傳名參數本質上是個方法

傳名參數實質上是壹個參數列表為空的方法,如下:

如上代碼實際上定義了壹個方法m1,m1的參數是個傳名參數(方法)。由於對於參數為空的方法來說,方法名就是方法調用

,所以List(x,x)實際上是進行了兩次方法調用。

由於List(x,x)是進行了兩次方法調用,所以得到兩個不同的值。

如果我們稍微修改壹下函數的m1的定義,把x先緩存起來,結果就會跟以前大不壹樣。