我基本上是新功能編程和scala,下面的問題可能看起來很愚蠢。函數文字 - 需要幫助理解代碼片段
val f = (a:Int) => a+1
在上面的代碼中,我應該考慮f
是一個函數或變量?來自C/C++的背景,首先想到的是f
是一個存儲匿名函數返回值的變量,但我認爲這不是解釋它的正確方法。任何解釋都會非常有用。
(一些我上面使用可能是錯相對於階/功能編程,術語的麻煩與它承擔)
我基本上是新功能編程和scala,下面的問題可能看起來很愚蠢。函數文字 - 需要幫助理解代碼片段
val f = (a:Int) => a+1
在上面的代碼中,我應該考慮f
是一個函數或變量?來自C/C++的背景,首先想到的是f
是一個存儲匿名函數返回值的變量,但我認爲這不是解釋它的正確方法。任何解釋都會非常有用。
(一些我上面使用可能是錯相對於階/功能編程,術語的麻煩與它承擔)
這裏,f
是存儲函數的變量。這是自說任何以下的真的沒有不同:
val a = 4 // `a` is a variable storing an Int
val b = "hi" // `b` is a variable storing a String
val f = (a:Int) => a+1 // `f` is a variable storing a function
您也可以使用REPL證實了這一點:
scala> val f = (a:Int) => a+1
f: Int => Int = <function1>
因此,這是告訴你,f
有型Int => Int
。換句話說,f
是一個函數,它帶有一個參數Int
,並返回一個Int
。
由於f
是一個變量,你可以調用它的方法,或者作爲參數傳遞給期待它的類型功能:
a + 3 // here I'm calling the `+` method on `a`, which is an Int
f(3) // here I'm calling the `apply` method on `f`, which is a function `Int => Int`
f(a) // the function `f` expects an `Int`, which `a` is
(1 to 3).map(f) // the `map` method expects a function from Int to Int, like `f`
是的,像DHG說,f
是一個變量(即可以」不能改變)存儲一個函數。
但是,這裏有一個細微之處:
...出現的第一個念頭是,f是存儲的匿名函數的 返回值
f
實際存儲的變量函數,不是結果。所以你可以給它不同的輸入,並得到不同的輸出。所以,你可以使用它像f(7)
然後f(5)
。 Scala中的函數是對象,因此可以分配給變量,作爲參數傳遞等。
I recently posted about function literals,這可能對您有所幫助。
f
是值表示函數文字。
在聲明中,右側是函數文字。左側將其綁定到一個名稱,該名稱隨後稱爲值(val
關鍵字與LISP中的let
類似)。現在該函數與符號f
相關聯,因此您可以使用此符號f
來引用該函數。
我不同意其他答案暗示f
應該被稱爲變量。f
是一個值,因爲它固定在確定的右側項目和不能更改。與此相反的變量,與var
介紹,讓你重新賦值給一個符號:
var f = (i: Int) => i + 1
凡var
開頭的變量定義,f
是名稱或變量的符號,有可能是一個可選: ...
定義了變量的類型(如果不填寫,類型將自動從作業推斷出),並且= ...
定義值最初的分配給該變量。
所以,當一個人說值,不要用數字常量混淆,它只是不改變的實體。一個函數也可以是一個值,因爲f
然後總是表示這個相同的函數,即使您可以用不同的參數來提供該函數,這些參數會產生不同的結果。
現在用var
你可以重新分配其右手邊:
f(2) // --> 3
f = (i: Int) => i * 2 // assign a new function to the variable f.
f(2) // --> 4
函數式編程是所有關於避免變量(重新分配)。
也可以定義一個函數,而根本不會將它分配給一個值或一個變量。下面定義了這樣的功能,並立即用參數4
稱之爲:
{ i: Int => i + 1 } apply 4 // --> 5
儘管這是作爲一個說法本身很少有用,但調用期望一個函數參數的方法時,你會看到「純」的功能往往。例如
val s = List(1, 2, 3)
s.map { (i: Int) => i + 1 } // --> List(2, 3, 4)
s.map { _ + 1 } // equivalent
s.map(_ + 1) // equivalent
帶上一粒鹽;正如在上面的評論中提到的那樣,即使在文獻中,'val'和'var'通常都被稱爲變量,可能使用「一次寫入」或「不變變量」來區分前者和後者。 –
不要說「變量」,這很混亂。這是一個價值,你不能用任何新的價值來覆蓋它。術語「變量」應該保留爲「var」,值應該用於「val」。它只是一個__place-holder__意義上的變量,這可能就是你的意思。 –
@ 0__:Scala規範使用單詞「變量」,即使值無法更改,Haskell規範也是如此,幾乎所有的數學教科書都是如此,等等。您可能認爲標準用法可能會引起混淆,但嘗試改變它不是一場你將要贏得的戰鬥。 –
@Travis,同意。 – dhg