2017-02-01 9 views
1
func runningMetersWithMetersPerDay (metersPerDay: Int) ->() -> 
Int { 
    var totalMeters = 0 
    return { 
     totalMeters += metersPerDay 
     return totalMeters 
    } 
} 
var planA = runningMetersWithMetersPerDay (metersPerDay: 2000) 
planA() 
planA() 

最初planA()プリント2000と第二planA()印刷4000 は数が、私はなぜ planA()を呼び出すたびに蓄積しますか? この機能ではvar totalMeters = 0をどのように使用していますか? runningMetersWith MetersPerDay (metersPerDay: 2000)と同じplanA()ですか? そうでない場合、それらの違いは何ですか? ご協力いただきありがとうございます。小さな機能に関する問題と閉鎖

答えて

1

あなたのメソッドはクロージャを返します。クロージャは2回実行されます。 閉鎖の環境を取り入れています。あなたのケースでは、 'outer'変数totalMetersが別の呼び出しによってその値を保持します。

これはあなたが望むものではない場合、あなたは次のように閉鎖にtotalMetersを配置する必要があるだろう:私が変更した :以下のコメントからの質問に答えるために

func runningMetersWithMetersPerDay (metersPerDay: Int) ->() -> 
Int { 
    return { 
     var totalMeters = 0 
     totalMeters += metersPerDay 
     return totalMeters 
    } 
} 

func runningMetersWithMetersPerDay (metersPerDay: Int) ->() -> 
    Int { 
     print ("rMWMD called") 
     var totalMeters = 0 
     return { 
      totalMeters += metersPerDay 
      print ("calculated new result: \(totalMeters)") 
      return totalMeters 
     } 
} 

print ("start") 
var planA = runningMetersWithMetersPerDay (metersPerDay: 2000) // "rMWMPD called" 
print ("got planA") 
planA() // "calculated new result:2000" 
planA() // "calculated new result:4000" 

runningMetersWithMetersPerDay (metersPerDay: 2000)() // "calculated new result: 2000" 
planA() // "calculated new result:6000" 
print ("end") 

planAが再です:元の関数と呼び出しは、いくつかのヒントを印刷しますrunningMetersWithMetersPerDay(())->Int - のクロージャはvoidを受け取り、を返します)クロージャを2回実行し、結果(2000、4000)を取得します。

さて、機能runningMetersWithMetersPerDay(metersPerDay:)が再び呼び出され、新しいクロージャを返し、この戻り値は、excecutedされます。変数に代入されていないにもかかわらず、新しいクロージャーなので、2000を返します。あなたはプラナ3回目の実行終わり

runningMetersWithMetersPerDay (metersPerDay: 2000) /* "rMWMPD called" and now call the closure: */() // "calculated new result: 2000" 

、まだそれが自分の状態(例えば自分のtotalMeters値)です保持しているため、それは何が起こっている6000

+0

こんにちは、あなたの答えに感謝します。しかし、私は別の小さな質問を見つける。最初にplanA()を2回呼び出し、結果が2000と4000を出力した後、runningMetersWithMetersPerDay(metersPerDay:2000)()を呼び出して結果を2000に出力し、planA()を呼び出して結果を6000に出力しました。 planA = runningMetersWithMetersPerDay(metersPerDay:2000)、planA()とrunningMetersWithMetersPerDay(metersPerDay:2000)()を呼び出すとどうして違うのですか? – Wilson

+0

@Wilson:私の変更された答えを見てください。 –

0

を返します。 次のようにそれを考えますここは正常です。 ステップバイステップで行きましょう。

まず、あなたが実行します。

var planA = runningMetersWithMetersPerDay (metersPerDay: 2000) 

を、あなたはここで何を実行していますか?

var totalMeters = 0 
return { 
    totalMeters += metersPerDay 
    return totalMeters 
} 

planAには何がありますか?

  1. 可変totalMeters
  2. fonction

このコンテキスト内で実行される準備ができて最初に実行、totalMeters = 0

{ 
    totalMeters += metersPerDay 
    return totalMeters 
}() 

セカンドランとコンテキスト、totalMeters = 2000

{ 
    totalMeters += metersPerDay 
    return totalMeters 
}() 

新しい結果= 4000

+1

こんにちは、お返事ありがとうございます。 – Wilson

+0

神田はアンドレアスと同時に答えました:)笑!ウィルソンを歓迎します。 – Mikael

関連する問題