2017-02-19 4 views
0

メソッド署名が以下の "counter"という名前のメソッドを実装しようとしているScala初心者。スカラ:返されたメソッド内のcount変数の別の状態

このメソッドは、整数nで呼び出されたときにステートフルな関数を返すように、ステートレス関数でなければなりません。このステートフル関数は、最初に呼び出された後にn、次にn + 1、次にn + 2などを返す必要があります。

カウンタは独立していなければならず、カウンタ(1)を2回実行すると、他の州。

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に別々のカウント変数を与えるかを理解することができないので、要件に応じて「お互いの状態を干渉しない」ことができます。

私は適切なトラックにいますか?どのような指針が最も高く評価されます。 valで、変数は唯一、ユーザーが定義したときにたまたま一度定義されているので

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

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

:あなたが定義しているカウンタ方法はdefvalからキーワードを変更する必要が

答えて

2

まず、the difference between def and valをチェックしてください。 TL;それのDRはvalが一度しか評価されないので、返す関数に到達する前にcounterに定義すると、実際にはカウント保持変数に依存できません。

わかりやすくするために、パターンマッチングをより明確にするために括弧を追加し、渡されたパラメータをcounterにキャプチャして、匿名関数のクロージャに格納する必要があったため戻る。

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

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

これは完全に機能しました。ありがとうございました! – shoogazer

+3

ここでは大したことではありませんが、 'returnVal'を' val'にします。 –

+0

良いコール@ジャスパー-M。 – bergren2

1

counterメソッドです。後ですべてのクロージャでこの変数を共有します。 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

関連する問題