为什么 go 中的 receiver name 不推荐使用 this 或者 self
来自公众号:新世界杂货铺
前言
在日常的开发中我们除了定义函数以外, 我们还会定义一些方法。这本来没有什么, 但是一些从PHP或者其他面向对象语言转GO的同学往往会把receiver name命名为this
, self
, me
等。
笔者在实际项目开发中也遇到类似的同学, 屡次提醒却没有效果,于是决心写下这篇文章以便好好说服这些同学。
CR标准做法
首先我们来看一下GO推荐的标准命名Receiver Names
,以下内容摘抄自https://github.com/golang/go/wiki/CodeReviewComments#receiver-names:
简单翻译总结有如下2点:
方法接受者名称应反映其身份, 并且不要使用
me
,this
,self
这些面向对象语言的典型标志符。在go中方法接受者其实就是方法的另一个参数。
Receiver是方法的第一个参数!
上面的第二点, 可能不是很好理解,所以我们直接看下面的demo:
通过上面的demo, 我们知道接受者可以直接作为第一个参数传递给方法的。而t.Println()
应该就是Go中的一种语法糖了。
到这里可能有同学又要问了, 既然Go提供了这种语糖,那我们这样命名有什么问题呢?笔者先不着急解释, 我们继续看下面的demo:
看上面的demo我们知道, 当receiver不是指针时调用SetA
其值根本没有改变。
因为Go中都是值传递,所以你如果对SetA的receiver的名称命名为this
, self
等,它就已经失去了本身的意义——“调用一个对象的方法就是向该对象传递一条消息”。而且对象本身的属性也并不一定会发生改变。
综上: 请各位读者在对receiver命名时不要再用this
, self
等具有特殊含义的名称啦。
Receiver是可以为nil的!!!
最近在研读h2_bundle.go
的时候,发现了一段特殊的代码,顿时惊出一身冷汗,姑在本文补充一下,以防止自己和各位读者踩坑。
源代码截图如下:
惊出我一身冷汗的正是图中标红的部分,receiver居然还要判断为nil!在我的潜意识里一直是这样认为的,receiver默认都是有值的,直接使用就行了。这简直颠覆我的认知,吓得我赶紧写了个demo验证一下:
上述输出如下:
a.test()
能够正常输出,只有在处理变量结构体内部变量v
才报出panic!!!还好本文前面已经介绍了Receiver是方法的第一个参数
。正因为是第一个参数所以仅仅作为参数传递时即使是nil
也能够正常调用函数,而在真正使用的地方报出panic。
鉴于receiver如此特殊,所以特意在本文完成之后补充后续内容以时刻提醒自己和各位读者。
本部分于20200827日晚补充。
最后, 祝各位事业有成!
版权声明: 本文为 InfoQ 作者【新世界杂货铺】的原创文章。
原文链接:【http://xie.infoq.cn/article/b216b08ea67b6eba1f73e2f22】。未经作者许可,禁止转载。
评论