Go|Go 读者提问(Go 函数返回值命名有存在的意义吗())
大家好,我是煎鱼。
在前两周我们在这篇《你能答对这道 Go 题目吗?超过 80% 的人都答错了...》文章中,针对题目,有小伙伴提出了如下问题:
【Go|Go 读者提问(Go 函数返回值命名有存在的意义吗())】
文章图片
为此,今天我们就来了解一下 Go 函数的返回值命名的意义是什么?
案例
函数 a 带返回值,函数 b 是不带返回值命名的例子。如下:
func a() (done func(), err error) {
return func() {
print("aaa: done")
}, nil
}func b() (func(), error) {
return func() {
print("aaa: done")
}, nil
}
这是日常工作中最常见的,前两年年我听到有同学不知道有命名返回值的用法,也不知道函数结尾返回个
return
的意义是什么,这有啥用?官方解释 在官方的《Effective Go》中,明确将带命名的返回值参数定义为 Named result parameters(命名的结果参数)。
函数签名如下:
func nextInt(b []byte, pos int) (value, nextPos int) {
带有三个明确的特征:
- Go 函数的返回或结果 "参数 "可以被命名并作为常规变量使用,就像传入参数一样。
- 当命名时,它们在函数开始时被初始化为其类型的零值。
- 如果函数执行没有参数的返回语句,结果参数的当前值被用作返回值。
return
没指定,则会默认返回声明的返回变量。官方定义的作用是:“可以使代码更短、更清晰”。像是给 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 的风格,就是显式命名了返回。
但也会带来可能存在的函数内返回的省略,以至于很多人新入门的朋友看不懂。又或是像是开头文章内所介绍的,带命名的返回参数写着写着变成递归函数,一手抖也是会出现的。
该特性,建议平时斟酌使用,短小精悍的可以考虑,又长又多的建议还是不要增加过多的繁琐了。
文章持续更新,可以微信搜【脑子进煎鱼了】阅读,本文 GitHub github.com/eddycjy/blog 已收录,学习 Go 语言可以看 Go 学习地图和路线,欢迎 Star 催更。推荐阅读
- 网友:Go 你是 Google 的,Go:我不是
- Go1.18 新特性:编译后的二进制文件,将包含更多信息
推荐阅读
- Python|Python 中的对象析构函数__del__ 详情
- 手写Spirit防抖函数underscore和节流函数lodash
- C++ STL Merge的用法
- c++|虚函数和多态性
- 一起来学习C++的函数指针和函数对象
- C语言中有哪些字符处理函数你知道吗
- Node.js基础入门之回调函数及异步与同步详解
- c++核心编程之函数的重载
- mysql之常用函数(核心总结)
- 神经网络|【机器学习基础】常用激活函数(激励函数)理解与总结