对不起,我不能在问题标题中更具体,但我正在阅读一些Go代码,我遇到了这种形式的函数声明:
func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { ... }
来自https://github.com/mattermost/platform/blob/master/api/context.go
func (s *GracefulServer) BlockingClose() bool { ... }
来自https://github.com/braintree/manners/blob/master/server.go
什么是(h handler)
与(s *GracefulServer)
括号之间是什么意思?考虑到括号之间事物的含义,整个函数声明意味着什么?
这与Go的功能和方法的区别是什么不重复?:这个问题来找我,因为我不知道函数名之前括号中的内容是什么,不是因为我想知道函数和方法之间有什么区别......如果我知道这个声明是一种方法我就不会'我们首先提出了这个问题.如果某人有一天和我有同样的疑问,我不相信她会去寻找"golang方法",因为她不知道情况就是这样.这就像想知道"sigma"字母在数学表达式之前的含义(不知道它意味着求和),并且有人说它是总和与其他事物之间差异的重复.
此外,这个问题的简短回答("它是接收者")无法回答"功能和方法之间的区别".
这被称为"接收器".在第一种情况下,(h handler)
它是值类型,在第二种情况下,(s *GracefulServer)
它是指针.在Go中工作的方式可能与其他语言有所不同.然而,接收类型在大多数面向对象的编程中或多或少地像一个类.这是你调用方法的东西,就像我把一些方法A
放在一些类中Person
然后我需要一个类型的实例Person
来调用A
(假设它是一个实例方法而不是静态!).
有一个问题在这里是接收器获取的情况下被推到像其他参数调用堆栈,所以如果接收者是一个值的类型,比如handler
,你将在的东西拷贝一起工作你的意思是这样调用的方法h.Name = "Evan"
会返回调用范围后不会保留.出于这个原因,任何期望改变接收器状态的东西都需要使用指针或返回修改后的值(如果你正在寻找它,则给出更多的不可变类型范例).
这是规范中的相关部分; https://golang.org/ref/spec#Method_sets
这意味着ServeHTTP
它不是一个独立的功能.函数名之前的括号是定义这些函数将在其上运行的对象的Go方式.所以,本质上ServeHTTP
是一个类型处理程序的方法,可以使用任何类型处理程序的对象(例如h)来调用.
h.ServeHTTP(w, r)
它们也被称为接收器.有两种方法可以定义它们.如果要修改接收器,请使用如下指针:
func (s *MyStruct) pointerMethod() { } // method on pointer
如果您不需要修改接收器,您可以将接收器定义为如下值:
func (s MyStruct) valueMethod() { } // method on value
来自Go playground的这个例子展示了这个概念.
package main import "fmt" type Mutatable struct { a int b int } func (m Mutatable) StayTheSame() { m.a = 5 m.b = 7 } func (m *Mutatable) Mutate() { m.a = 5 m.b = 7 } func main() { m := &Mutatable{0, 0} fmt.Println(m) m.StayTheSame() fmt.Println(m) m.Mutate() fmt.Println(m)
上述程序的输出是:
&{0 0} &{0 0} &{5 7}