此递归函数按预期工作(返回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)
行)
有人可以解释这种行为吗?
答案 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)
}
但是,您可能希望将sync.WaitGroup
传递给您的函数,而不是睡觉。