2014-03-03 34 views
3

我試圖理解引用的這兩種方法之間的關鍵區別/定義Function Literal(參考):函數文本引用和高清

通過val

scala> val v2 = new Function[Int, Int] { 
    | def apply(a: Int): Int = a + 1 
    | } 
v2: Int => Int = <function1> 

而且通過def

scala> def f2 = new Function[Int, Int] { 
    | def apply(a: Int): Int = a + 1 
    | } 
f2: Int => Int 

看起來它在使用方面幾乎相同。我可以將v2f2傳遞給接受(Int) => Int作爲參數的函數。傳遞參數給它..

我想還是V2它創建了一個Function1對象是指Function1對象..喜歡一個proxy的情況?

好的..我的問題是:第1和第2種方法的優缺點是什麼?

它的定義是def,它還是Function Literal

+1

可能的重複http://stackoverflow.com/a/18887341/985949 – Mik378

+0

看到接受的答案在這裏:http://stackoverflow.com/questions/19607485/def-or-val-for-defining-function-在-階?RQ = 1。基本上它是一個方法(def)vs函數對象(val),但兩者幾乎相同。 –

回答

3

首先,無論你的例子實際上是功能文字 -you're創建在普通的舊無糖方式Function實例,其實你可以使用這個方法(new Function { ... })創建一個實例來自Java代碼的scala.Function

下面都是函數文本,並完全等同於你的定義:

val v2 = (a: Int) => a + 1 
def f2 = (a: Int) => a + 1 

這裏唯一的區別是,val將一勞永逸地創建一個實例,無論多少次您使用v2(即使您從不使用它),而def將每次創建一個新實例(或根本不創建,如果您從未使用它)。所以你通常會想用val去。

但是,有些情況下需要使用def。考慮以下幾點:

def myIdentity[A] = (a: A) => a 

有沒有辦法,我們可以這樣寫一個val,因爲Scala沒有多態函數在這個意義上(爲Function[A, B]AB任何實例必須是具體的類型)。但是我們可以定義一個返回函數的多態方法,當我們編寫例如myIndentity(1),A將被推斷爲Int,我們將創建(並應用)一個完全按照您的預期的Function[Int, Int]

+0

如果它們完全等同於我的定義,並且由於它是語法糖,它們應該是函數文字(?)。首先我想出你的簡單例子 - 結果/輸出看起來是一樣的。 – ses

+2

在這種情況下,術語_literal_專指語法,因此您可以將加糖版本稱爲函數文字,但不能通過'new'將簡單的舊實例化。 –

+1

@ses'4'和'(2 + 2)'完全等價,但第一個是整數字面值,第二個不是。同樣在這裏。 –