this
this
, self
, me
, self
,
먼저 GOReceiver Names
,以下内容摘抄自https://github.com/golang/go/wiki/CodeReviewComments#receiver-names:
The name of a method's receiver should be a reflection of its identity; often a one or two letter abbreviation of its type suffices (such as "c" or "cl" for "Client"). Don't use generic names such as "me", "this" or "self", identifiers typical of object-oriented languages that gives the method a special meaning. In Go, the receiver of a method is just another parameter and therefore, should be named accordingly. ...
简单翻译总结有如下2点:
方法接受者名称应反映其身份, 并且不要使用me
, this
, self
에서 권장하는 표준 명명법을 살펴보겠습니다. 객체지향 언어의 일반적인 식별자입니다.
이동에서 메소드 수신자는 실제로 메소드의 또 다른 매개변수입니다.
위의 두 번째 사항은 이해하기 쉽지 않을 수 있으므로 아래 데모를 살펴보겠습니다.
// T ... type T int // Println ... func (t T) Println() { fmt.Println("value: %v", t) } func main() { t := T(1) t.Println() T.Println(t) // receiver作为函数的第一个参数,这个时候发生值拷贝,所以方法内部的t变量是真实t变量的一个拷贝 // 这和this的含义是不相符的 } // output: value: 1 value: 1
通过上面的demo, 我们知道接受者可以直接作为第一个参数传递给方法的。而t.Println()
应该就是Go中的一种语法糖了。
到这里可能有同学又要问了, 既然Go提供了这种语法糖,那我们这样命名有什么问题呢?笔者先不着急解释, 我们继续看下面的demo:
// Test ... type Test struct { A int } // SetA ... func (t Test) SetA(a int) { t.A = a } // SetA1 ... func (t *Test) SetA1(a int) { t.A = a } func main() { t := Test{ A: 3, } fmt.Println("demo1:") fmt.Println(t.A) t.SetA(5) fmt.Println(t.A) t1 := Test{ A: 4, } fmt.Println("demo2:") fmt.Println(t1.A) (&t1).SetA1(6) fmt.Println(t1.A) } // output: demo1: 3 3 demo2: 4 6
看上面的demo我们知道, 当receiver不是指针时调用SetA
其值根本没有改变。
因为Go中都是值传递,所以你如果对SetA的receiver的名称命名为this
, self
等,它就已经失去了本身的意义——“调用一个对象的方法就是向该对象传递一条消息”。而且对象本身的属性也并不一定会发生改变。
综上: 请各位读者在对receiver命名时不要再用this
, self
等具有特殊含义的名称啦。
最近在研读h2_bundle.go
的时候,发现了一段特殊的代码,顿时惊出一身冷汗,姑在本文补充一下,以防止自己和各位读者踩坑。
源代码截图如下:
惊出我一身冷汗的正是图中标红的部分,receiver居然还要判断为nil!在我的潜意识里一直是这样认为的,receiver默认都是有值的,直接使用就行了。这简直颠覆我的认知,吓得我赶紧写了个demo验证一下:
type A struct { v int } func (a *A) test() { fmt.Println(a == nil) } func (a *A) testV() { fmt.Println(a.v) } func main() { var a *A a.test() a.testV() }
上述输出如下:
a.test()
能够正常输出,只有在处理变量结构体内部变量v
才报出panic!!!还好本文前面已经介绍了Receiver是方法的第一个参数
。正因为是第一个参数所以仅仅作为参数传递时即使是nil
일반적으로 함수를 호출하고 해당 함수가 실제로 사용되는 곳에서 패닉을 보고할 수도 있습니다.
위 내용은 go에서 수신자 이름으로 this 또는 self를 사용하는 것이 권장되지 않는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!