这样写为什么会造成死循环

来源:7-3 函数式编程例二

Kinopio

2019-11-18

func (node *Node) TraverseFunc(f func(*Node)) {
	if node== nil{
		return
	}
	node.Left.TraverseFunc(f)
	f(node)  // 此处如果写成 node.TraverseFunc(f) 就会造成死循环
	node.Right.TraverseFunc(f)
}

我测试了 node.TraverseFunc(f)下会死循环,报错,为什么不能这样写呢?
runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow

runtime stack:
runtime.throw(0x10d222a, 0xe)

写回答

3回答

EnzoLiu

2020-07-21

首先明确两点:

  1. f 是通过参数传递进来的

  2. f 是个函数

至于f(node),你可以理解为在TraverseFunc外面定义了一个函数传递进来执行了


而node.TraverseFunc(f)写法 既不是左子树也不是右子树

这是在当前节点上不断的去自己调用自己,产生了死循环

这就像是下面的代码:

func abc() {

    abc()

}

0
0

慕函数8409050

2019-11-29

因为确实写了一个死循环。
你可以假定一个简单情况,逐行分析代码的执行。

例如:遍历只有一个节点的树。

1. 这个函数的退出条件是

if node== nil{
    return
}

2. 接下来这一行,由于左节点是nil,正常退出执行到下一行

node.Left.TraverseFunc(f)

3. 而你在程序中 又调用当前节点的遍历

node.TraverseFunc(f)

当前节点不是nil,所以无法达到退出的条件,就死循环。

所有递归调用的函数都执行到第三步,最终导致栈溢出。

0
0

leyou240

2019-11-18

这样会死循环。新手不懂的话,建议你调试跟踪调试调试

0
0

Google资深工程师深度讲解Go语言 由浅入深掌握Go语言

语法+分布式爬虫实战 为转型工程师量身打造

5995 学习 · 1909 问题

查看课程