2017-02-19 13 views
0

Scala新手試圖實現名爲「counter」的方法簽名位於下方的方法。Scala:在返回的方法內單獨計數變量的狀態

該方法應該是一個無狀態函數,以便當它用整數n調用時,它返回一個有狀態函數。這個有狀態函數應該在第一次調用時返回n,然後返回n + 1,然後n + 2等。

計數器必須是獨立的,以便計數器(1)運行兩次會產生兩個不會干擾每個函數的函數他人的狀態。

下面是我到目前爲止有:

val counter : Int =>() => Int = { 
    // Complete definition below. 
    var count = 0 

    n: Int =>() => { 
     var returnVal = n + count 
     count = count + 1 
     returnVal 
    } 
} 

的計數器是如何被調用的例子:

assert ({ 
    val k1 :() => Int = counter (1) 
    val k2 :() => Int = counter (2) 
    val r1 : Int = k1() 
    val r2 : Int = k1() 
    val r3 : Int = k2() 
    val r4 : Int = k2() 
    val r5 : Int = k2() 
    val r6 : Int = k1() 
    (r1, r2, r3, r4, r5, r6) 
    } === (1, 2, 2, 3, 4, 3) 
) 

當運行斷言,我實現計數器返回(1,2,4 ,5,6,6)。

我相信這是由於k1和k2都指向相同的計數變量。然而,我無法弄清楚如何按照要求爲k1和k2提供他們自己的單獨計數變量,以便它們「不會互相干擾對方的狀態」。

我在正確的軌道上嗎?任何指導將不勝感激。

回答

2

,先看看the difference between def and val。它的TL; DR是val將只評估一次,因此如果在到達要返回的函數之前將其定義在counter中,則無法真正依賴於計數保持變量。爲了使它更清晰,我添加了括號以使模式匹配更加明顯並將該行分開,因爲我們需要捕獲傳入的參數並將其存儲在匿名函數的閉包中返回。

val counter : Int =>() => Int = { 
    (n: Int) => { 
    var count = n 

    () => { 
     val returnVal = count 
     count = count + 1 
     returnVal 
    } 
    } 
} 
+0

這工作完美。謝謝! – shoogazer

+3

這裏並不重要,但我會將'returnVal'設爲'val'。 –

+0

好電話@ Jasper-M。 – bergren2

1

您需要從val關鍵字改爲def爲您所定義的計數器方法:

def counter : Int =>() => Int = { 
    // Complete definition below. 
    var count = 0 

    n: Int =>() => { 
     var returnVal = n + count 
     count = count + 1 
     returnVal 
    } 
} 

因爲隨着val,該計數變量只被定義一次,當您定義的發生專櫃方法,所以後面的所有關閉會分享這個變量;與def方法,計數變量將重新定義每次您撥打計數器(n)


很容易地看到這一點,如果你var count = 0行後添加一個println:

scala> val counter : Int =>() => Int = { 
      // Complete definition below. 
      var count = 0 
      println(count) 

      n: Int =>() => { 
       var returnVal = n + count 
       count = count + 1 
       returnVal 
      } 
     } 

0           // 0 is printed here 
counter: Int => (() => Int) = <function1> 

scala> val k1 = counter(1)     // nothing prints here 
k1:() => Int = <function0> 

scala> val k2 = counter(2)     // nothing prints here 
k2:() => Int = <function0> 
+0

謝謝,這樣做更有意義。不幸的是,我必須按照任務的指導方針保留val關鍵字。 – shoogazer