你能答对这道 Go 题目吗?超过 80% 的人都答错了...

Posted 脑子进煎鱼了

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了你能答对这道 Go 题目吗?超过 80% 的人都答错了...相关的知识,希望对你有一定的参考价值。

所返回的 done 值来输出程序,应当是:

实际上是一个赋值语句。结合程序,可以看到函数 bbb 的第一个返回值是 done 参数。

如下:

在程序最后执行 return 语句后,会对返回变量 done 进行赋值,自然该值不会是由函数 aaa 所设置的了。

这是一个关键的地方。

执行完毕后, 变量 done 已经变成了一个递归函数。

递归的过程是:函数 bbb 调用变量 done 后,会输出 bbb: surprise! 字符串,然后又调用变量 done。而变量 done 又是这个闭包(匿名函数),从而实现不断递归调用和输出。

最终结果如下:

b: surprise!bbb: surprise!bbb: surprise!runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0xc0200e0380 stack=[0xc0200e0000, 0xc0400e0000]
fatal error: stack overflow

runtime stack:
runtime.throw(0x1074b5a, 0xe)
        /usr/local/Cellar/go/1.16.6/libexec/src/runtime/panic.go:1117 +0x72
runtime.newstack()
        /usr/local/Cellar/go/1.16.6/libexec/src/runtime/stack.go:1069 +0x7ed
runtime.morestack()
        /usr/local/Cellar/go/1.16.6/libexec/src/runtime/asm_amd64.s:458 +0x8f
...

也就是正确答案是:D,程序最终运行出错。

一直调用一直爽,直至栈溢出程序崩溃。

总结

这位大佬出的题目,本质上是比较烦人的,其结合了函数返回参数的命名用法。

如果我们把这个函数的返回参数命名去掉,就可以避开这个问题。如下:

func bbb() (func()error) 
 ...
 return func()  
   print("bbb: surprise!"); 
   done() 
 , err

...

输出结果为 "bbb: surprise!"。

很多 Go 的同学在日常代码编写的时候不会用到或注意到。但如果写的时候有类似案例代码中的模式,就会排查许久都查不到。

这是个有警惕意义的题目,你觉得呢?

参考
  • twitter 上的原题目
  • Go 语言返回值是引用时return后省略是推荐写法吗?

  • 关注煎鱼,获取业内第一手消息和知识

    Go 返回值命名还有存在的必要吗?

    大家好,我是煎鱼。

    在前两周我们在这篇《你能答对这道 Go 题目吗?超过 80% 的人都答错了...》文章中,针对题目,有小伙伴提出了如下问题:

    为此,今天我们就来了解一下 Go 函数的返回值命名的意义是什么?

    的意义是什么,这有啥用?

    没指定,则会默认返回声明的返回变量。

    官方定义的作用是:“可以使代码更短、更清晰”。像是给 nextInt 函数的返回的结果命名,那你就能很明确知道,第一个返回的值是 value,第二个是 nextPos,起到显式声明的作用。

    建议

    在官网的《A Tour of Go》中明确指出 Named result parameters 只建议在较短的函数中使用。

    例如以下例子:

    func split(sum int) (x, y int) 
     x = sum * 4 / 9
     y = sum - x
     return


    func main() 
     fmt.Println(split(17))

    如果是在较长的函数中使用,它们会损害可读性。也见过因为写的太长了,为了优化可读性,不断换行的代码编写,越搞越繁琐的场景。

    总结

    实际上带命名的返回参数,比较带有 Go 的风格,就是显式命名了返回。

    但也会带来可能存在的函数内返回的省略,以至于很多人新入门的朋友看不懂。又或是像是开头文章内所介绍的,带命名的返回参数写着写着变成递归函数,一手抖也是会出现的。

    该特性,建议平时斟酌使用,短小精悍的可以考虑,又长又多的建议还是不要增加过多的繁琐了。

    推荐阅读
  • 网友:Go 你是 Google 的,Go:我不是
  • Go1.18 新特性:编译后的二进制文件,将包含更多信息
  • 关注煎鱼,获取业内第一手消息和知识

    以上是关于你能答对这道 Go 题目吗?超过 80% 的人都答错了...的主要内容,如果未能解决你的问题,请参考以下文章

    80%的人都答不出来的 Android Framework面试题,整理给大家

    阿里java面试题,你能答对多少?

    这道 CSS 题目,57% 的开发者都答错了,你会吗?

    你确定Java注释不会被执行吗?80%的人都不知道

    你确定Java注释不会被执行吗?80%的人都不知道

    Java中的 BigDecimal,80%的人都用错了....

    (c)2006-2024 SYSTEM All Rights Reserved IT常识