2016-10-25 14 views
1

我無法解釋指定爲沒有LHS(左手側)的函數參數的「double-rightarrow Type」。 () => Int()Int但是=> Int是什麼意思? 例如請參閱下面的foo方法的第一個參數,f的類型是什麼?是(Int,() => Int) => Int在函數參數中沒有LHS平均值的「雙向右箭頭類型」什麼是

對於bar的定義,其中y是按名稱傳遞的,我將它解釋爲一個沒有參數的函數,該參數將生成一個Int,它看起來等同於baz的定義。

我可以嘗試有理由相信,在f需要foo第二個參數爲呼叫的名字,而不是來自() => Int但就是矛盾這一事實,barbaz定義在javap的相同。我錯過了什麼?

object ParamTest { 
    def foo(f: (Int, => Int) => Int, x: Int) : Int = 10 
    def bar(x: Int, y: => Int) : Int = 20 
    def baz(x: Int, f:() => Int) : Int = 30 
    def qux(f: (Int,() => Int) => Int, x: Int) : Int = 40 
} 

爲了測試我編譯上述類scalac ParamTest.scala

javap ParamTest給我:

public final class ParamTest { 
    public static int qux(scala.Function2<java.lang.Object, scala.Function0<java.lang.Object>, java.lang.Object>, int); 
    public static int baz(int, scala.Function0<java.lang.Object>); 
    public static int bar(int, scala.Function0<java.lang.Object>); 
    public static int foo(scala.Function2<java.lang.Object, scala.Function0<java.lang.Object>, java.lang.Object>, int); 
} 

這似乎表明,foo和qux具有相同的方法簽名。換句話說,我可以解釋=> Int() => Int,但 foo(baz,100)給了我一個類型不匹配錯誤

scala> import ParamTest._ 
import ParamTest._ 

scala> foo(bar,100) 
res0: Int = 10 

scala> foo(baz,100) 
<console>:11: error: type mismatch; 
found : (Int,() => Int) => Int 
required: (Int, => Int) => Int 
       foo(baz,100) 
       ^

編輯:這是不一樣的this question。我不是問call-by-name: => Type() => Type之間的實際區別。內部知道我知道的更有趣。 scala如何區分兩者,當javap或cfr decompilation給出fooqux的相同定義時;併爲barbaz

回答

2

正如你所發現的,() => A=> A不是一回事。

按名稱調用(即=> A)只是意味着:「延遲評估此方法參數」。換句話說,懶惰的評價。

def f(x: Int, y: => Int) = ??? 

f(3+5, 2+4) 

在本例的3 + 5的添加是在調用位置完成,並且x值爲8加入的2 + 4,在另一方面,不這樣做,直到y在內部參考方法的主體f()。如果該引用位於未執行的if...else...分支中,則添加永遠不會完成。

對於像Int這樣的簡單評估來說,這是非常沒有意義的,但如果參數是一個昂貴的評估,它會變得更有意義,如果它是帶有副作用的代碼塊。

所以,在回答你的問題,的f: (Int, => Int) => Int的意思是:「f需要兩個參數併產生Int,參數是2個Int S,第二這是懶洋洋地評估。「

+0

謝謝,我很感謝你的解釋。你知道我在哪裏可以找到更多關於Scala規範的細節嗎?我試着通過[4.6節](http://www.scala-lang.org/files/ archive/spec/2.11/04-basic-declarations-and-definitions.html),但是如果沒有LHS的副名參數:(但至少我的混淆被清除了,所以我可以繼續前進 – vsnyc

+0

嗯,我不知道斯卡拉規範,但還有其他方法可以獲得這些信息,正如已經指出的那樣,搜索已經被問到的問題是一個很好的開始,另外,在Scala中編程「(第1版)可在[在線](http://www.artima.com/pins1ed/)。除此之外,還有許多博客文章。將一些術語插入搜索引擎併爲有用的書籤添加書籤。 – jwvh

+0

我已經閱讀了端到端的[本教程](http://www.scala -lang.org/docu/files/ScalaByExample.pdf),並完成了他在Coursera的前兩門課程。我想知道的是,在兩種情況下,當反編譯類文件時,Scala如何區分'()=> A'和'=> A'兩種類型。但這個問題還不夠清楚,所以我會問一個新問題。你肯定幫助了懶惰的評估部分。 – vsnyc

相關問題