题目
Redhat的首席工程师、Prometheus开源项目Maintainer Bartłomiej Płotka 在Twitter上出了一道Go编程题,结果超过80%的人都回答错了。
题目如下所示,回答下面这段程序的输出结果。
// named_return.go package main import "fmt" func aaa() (done func(), err error) { return func() { print("aaa: done") }, nil } func bbb() (done func(), _ error) { done, err := aaa() return func() { print("bbb: surprise!"); done() }, err } func main() { done, _ := bbb() done() }
- A:
bbb: surprise!
- B:
bbb: surprise!aaa: done
- C: 编译报错
- D: 递归栈溢出
大家可以先思考下这段代码的输出结果是什么。
解析
在函数bbb
最后执行return语句,会对返回值变量done
进行赋值,
done := func() { print("bbb: surprise!"); done() }
注意:闭包func() { print("bbb: surprise!"); done() }
里的done
并不会被替换成done, err := aaa()
里的done
的值。
因此函数bbb
执行完之后,返回值之一的done
实际上成为了一个递归函数,先是打印"bbb: surprise!"
,然后再调用自己,这样就会陷入无限递归,直到栈溢出。因此本题的答案是D
。
那为什么函数bbb
最后return的闭包func() { print("bbb: surprise!"); done() }
里的done
并不会被替换成done, err := aaa()
里的done
的值呢?如果替换了,那本题的答案就是B
了。
这个时候就要搬出一句老话了:
This is a feature, not a bug
我们可以看下面这个更为简单的例子,来帮助我们理解:
// named_return1.go package main import "fmt" func test() (done func()) { return func() { fmt.Printl
文章评论