Go每日面试一题第二日
感谢题目来源 【Go语言中文网】 https://mp.weixin.qq.com/s/g0c00X674Bayc89AZu1bvA
题目:下面的代码能编译通过吗?可以的话输出什么,请说明?
Example1
var f = func(i int) { print("x") } func main() { f := func(i int) { if i > 0 { f(i - 1) } } f(10) }
原文的解析为:参考答案及解析:10x。这道题一眼看上去会输出 109876543210,其实这是错误的答案,这里不是递归。假设 main() 函数里为 f2(),外面的为 f1(),当声明 f2() 时,调用的是已经完成声明的 f1()。
看下面这段代码你应该会更容易理解一点:
Example2
var x = 23 func main() { x := 2*x - 4 println(x) // 输出:42 }
大家可能开始和我有同样的疑惑变量名都为f,main函数里调用f为递归调用。这里需要考虑一个问题-->Example1中var 定义的f为全局变量,main函数中开始的f变量为局部变量,将一个函数赋值给变量,当函数初始化完毕后才会赋值给变量,所以函数中的f就不可能是main函数中的变量f,只能是全局变量f。为了验证这一想法,进行了以下操作。
var f = func(i int) { print("x") } func main() { fmt.Println("44444", f) f := func(i int) { print("3333\n",i) if i > 0 { fmt.Println("1111\n",f) f(i - 1) } } fmt.Println("22222\n",f) f(10) }
输出为:
44444 0x1099390 22222 0x10993f0 3333 101111 0x1099390 x
可以发现44444对应的内存地址和1111对应的内存地址一致,所以以上想法成立。