函数声明语法:在函数名称前的括号中的东西

对不起,我不能在问题标题中更具体,但是我正在阅读一些Go代码,并且遇到了这种forms的函数声明:

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的方法”,因为她不知道情况是这样的。 这就好比想知道在mathexpression式之前“sigma”是什么意思(不知道它意味着总结),有人说这是summation和其他东西之间的区别的重复。

另外,这个问题(“它是一个接收者”)的简短答案并不是“function和方法之间有什么区别”的答案。

这被称为“接收者”。 在第一种情况下(h handler)它是一个值types,在第二个(s *GracefulServer)它是一个指针。 Go在Go中的工作方式可能与其他一些语言有所不同。 然而,接收types在大多数面向对象编程中或多或less地像一个类一样工作。 这是你调用方法的东西,就像是如果我把一些方法A放在一些类Person那么我将需要一个Persontypes的实例来调用A (假设它是一个实例方法,而不是静态的!)。

这里的一个问题是,接收器像其他参数一样被推入到调用堆栈中,所以如果接收器是一个值types,就像handler的情况一样,那么您将会从一个类似于h.Name = "Evan"在您返回到调用范围后不会持续。 因为这个原因,任何希望改变接收者状态的东西,都需要使用一个指针或者返回修改后的值(如果你正在寻找的话,给出更多的不可变types范例)。

这里是规范的相关部分。 https://golang.org/ref/spec#Method_sets

这意味着ServeHTTP不是一个独立的function。 函数名前的圆括号是定义这些函数将在其上运行的对象的Go方式。 所以,本质上ServeHTTP是一个types处理程序的方法,可以使用types处理程序的任何对象,例如h来调用。

 h.ServeHTTP(w, r) 

他们也被称为接收者。 有两种方法来定义它们。 如果你想修改接收器使用一个像这样的指针:

 func (s *MyStruct) pointerMethod() { } // method on pointer 

如果您不需要修改接收器,则可以将接收器定义为如下值:

 func (s MyStruct) valueMethod() { } // method on value 

Go操场的这个例子展示了这个概念。

 package main import "fmt" type Mutatable struct { a int b int } func (m Mutatable) StayTheSame() { ma = 5 mb = 7 } func (m *Mutatable) Mutate() { ma = 5 mb = 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}