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对应的内存地址一致,所以以上想法成立。

posted @ 2019-12-04 10:29  骑猪少年  阅读(109)  评论(0编辑  收藏  举报