golang递归函数将自身称为goroutine并不像预期的那样工作

时间:2016-09-18 04:54:46

标签: recursion go goroutine

此递归函数按预期工作(返回5行,数字为5到1):

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

这个没有(只返回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)
}

不同之处在于,在第二个实现中,函数将自身称为goroutine。 (第go recur(iter-1)行)

有人可以解释这种行为吗?

2 个答案:

答案 0 :(得分:8)

如果你使所有内容都异步,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()
}

答案 1 :(得分:1)

在所有goroutine完成之前,您的编程正在退出。查看此工作的最简单方法如下。

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传递给您的函数,而不是睡觉。