2016-01-03 55 views
1

我想學習scala並理解函數和方法之間的區別。如何從scala中的匿名函數中獲取值?

這是非常簡單的代碼,我寫 -

scala> class C (acc:Int) { 
     | val minc = (acc + 1) 
     | val func = {() => acc += 3 } 
     | } 

    scala> val c1 = new C(3) 
     c1: C = [email protected] 

    scala> c1.minc 
     res2: Int = 4 

    scala> c1.func 
     res3:() => Int = <function0> 

我理解的實例化對象C1調用函數func的該結果被存儲爲另一種表達RES3。

但是我想獲取價值的匿名函數()= ACC +3即C級

內。如果我試圖通過參數RES3表達斯卡拉拋出一個錯誤

scala> res3(4) 
    <console>:11: error: too many arguments for method apply:()Int in trait Function0 
    res3(4) 
     ^

如何從中獲得價值?

PS - 我剛剛開始使用scala,不知道這是否完全可能?

回答

5

這是你的func定義:

val func = {() => acc += 3 } 

讓我們來看看什麼是func類型的REPL看看。

scala> val c1 = new C(3) 
val c1 = new C(3) 
c1: C = [email protected] 

scala> c1.func 
c1.func 
res29:() => Unit = <function0> 

用普通的英語,這意味着「func指的是一個不接受參數且不返回值的函數。 Unit表示該方法不返回任何內容。如果您來自Java,那麼它與void類似,作爲返回類型。 function0表示它接受0個參數。

接下來,讓我們來看看示例中的失敗呼叫。

scala> c1.func(4) 
c1.func(4) 
<console>:10: error: too many arguments for method apply:()Unit in trait Function0 
       c1.func(4) 
        ^

現在我們知道了func的方法簽名,這個錯誤信息應該更有意義。我們知道func引用了一個不接受參數的函數,但在此調用中,您試圖用一個整數參數來調用它。由於方法調用的參數太多,因此Scala會將此誤報爲錯誤。

我不完全確定你想通過傳遞4作爲參數來做什麼。我最好的猜測是你試圖通過將3添加到acc然後將它返回給調用者來應用該函數來計算其結果。如果我是正確的,那麼我們可以重新定義C就象這樣:

class C(var acc:Int) { 
    val minc = (acc + 1) 
    val func =() => { 
    acc += 3 
    acc 
} 

scala> val c1 = new C(3) 
val c1 = new C(3) 
c1: C = [email protected] 

scala> c1.func() 
c1.func() 
res44: Int = 6 

當我們調用c1.func(),沒有傳遞參數,以便它能夠正確定義的方法簽名匹配。

另一種可能性是,您嘗試參數化增量並在調用中將4傳遞給它。如果是這樣,那麼你可以這樣做:

class C(var acc:Int) { 
    val minc = (acc + 1) 
    val func = (delta: Int) => { 
    acc += delta 
    acc 
    } 
} 

scala> c1.func(4) 
c1.func(4) 
res45: Int = 7 

在這種情況下,我們已經聲明匿名函數接受Int 1個型參數,所以當我們在方法調用傳遞4,它正確的方法簽名匹配。

0

您並未以您想的方式聲明匿名函數。這條線:

val func = {() => acc += 3 } 

這實際上宣告匿名函數。括號是第一個匿名函數(不帶參數),() => acc += 3是第二個函數。通過使用括號,Scala允許您聲明一個0元的匿名函數。如果你放棄這些,你會得到你想要的:

val func =() => acc += 3 

作爲一個附註,你可以在類型簽名中看到這一點。您當前的func簽名是:

() => Int = <function0> 

這是一個函數,0參數,並返回一個整數。這不是你想要的。當你把它改變什麼,我給你,你會得到這樣的:

Int => Int = <function1> 

現在func接受一個參數,並且整數,並返回另一個整數,這是你想要的。

+0

謝謝你的解釋!但是,當我嘗試從功能中獲得價值時,我仍然看到錯誤。 類別c(ACC:智力){ VAL MINC =(ACC + 1) VAL FUNC =()=> ACC + 3 } VAL C1 =新C(5) c1.minc打印6 但是,c1.func打印res23:()=> Int = 我期待輸出8出這個對象。有沒有其他方法可以用來從func中獲取價值? – GoldenPlatinum