2016-09-18 5 views
-1

この再帰関数は、(1までの数字5と5行を返す)作品自体を呼び出す:golang再帰関数予想通りゴルーチンが動作しないよう期待通り

package main 
import (
    "fmt" 
) 
func recur(iter int) { 
    if iter <= 0 { 
     return 
    } 
    fmt.Println(iter) 
    recur(iter-1) 
} 
func main() { 
    recur(5) 
} 

この1つは(リターンだけで1行ありません番号5)と:

package main 
import (
    "fmt" 
) 
func recur(iter int) { 
    if iter <= 0 { 
     return 
    } 
    fmt.Println(iter) 
    go recur(iter-1) 
} 
func main() { 
    recur(5) 
} 

差は、第2の実施形態では、関数はゴルーチンとして自分自身を呼び出すことです。 (行go recur(iter-1)

誰かがこの現象を説明できますか?

+0

goルーチンを使用するには、時間が必要です。 –

答えて

7

すべてを非同期にすると、mainには何も待機しません。あなたは明示的にgoルーチンを待たなければならないので、プログラムは再帰プロセスが終了する前に終了しません。

同期のためにsync.WaitGroupなどを使用してください。例(On Play):

func recur(iter int, g *sync.WaitGroup) { 
    defer g.Done() 
    if iter <= 0 { 
     return 
    } 
    fmt.Println(iter) 
    go recur(iter-1, g) 
} 

func main() { 
    g := &sync.WaitGroup{} 
    runs := 5 
    g.Add(runs) 
    recur(runs, g) 
    g.Wait() 
} 
+0

グラフをトラバースするとき、各再帰でブランチの量が不明です。可能性のあるリファクタリング:mainを含む各 'recur()'の前に 'Add(1)'を呼び出します。例:https://play.golang.org/p/OuZVgowAbt –

1

すべてのゴルーチンが終了する前に、プログラミングが終了しています。この作業を見るための最も簡単な方法は次のとおりです。

package main 

import (
    "fmt" 
    "time" 
) 

func recur(iter int) { 
    if iter <= 0 { 
     return 
    } 
    fmt.Println(iter) 
    go recur(iter - 1) 
} 
func main() { 
    recur(5) 
    time.Sleep(time.Second) 
} 

playground link

よりもむしろ寝て、しかし、あなたはあなたの機能に至るまでsync.WaitGroupを通過したいことがあります。

+0

ありがとうございます。ただ自分自身を実現し、確認するために同じスリープラインを追加しました:) – RSH

関連する問題