Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function declaration syntax: things in parenthesis before function name

Tags:

go

I'm sorry I couldn't be more specific in the question title, but I was reading some Go code and I encountered function declarations of this form:

func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {     ... } 

from https://github.com/mattermost/platform/blob/master/api/context.go

func (s *GracefulServer) BlockingClose() bool {     ... } 

from https://github.com/braintree/manners/blob/master/server.go

What does the (h handler) and the (s *GracefulServer) between parenthesis mean? What does the entire function declaration mean, taking into account the meaning of the things between parenthesis?

Edit

This is not a duplicate of Whats the difference of functions and methods in Go? : this question came to me because I didn't know what the things in parenthesis before the function name were, not because I wondered what was the difference between functions and methods... if I knew that this declaration was a method I wouldn't have had this question in the first place. If someone has the same doubt as me one day, I don't believe she will go searching for "golang methods" because she doesn't know that this is the case. It would be like wondering what the letter "sigma" means before a mathematical expression (not knowing it means summation) and someone says it's a duplicate of what's the difference between summation and some other thing.

Also, the short answer to this question ("it's a receiver") is no answer to "what's the difference between functions and methods".

like image 469
Marcus Vinícius Monteiro Avatar asked Dec 01 '15 22:12

Marcus Vinícius Monteiro


People also ask

What is the term called before the function name?

The parenthesis before the function name is the Go way of defining the object on which these functions will operate. So, essentially ServeHTTP is a method of type handler and can be invoked using any object, say h, of type handler. h.ServeHTTP(w, r) They are also called receivers.

What is the correct syntax for function declaration?

Declaring a function - function prototypestype functionName( type [argname] [, type, ...] ); Example: // declare a function prototype for the add function, taking two integer // arguments and returning their sum int add (int lhs, int rhs); In C and C++, functions must be declared before the are used.

What are the 3 common parts of declaring functions?

The function body has three parts: an optional declarative part, an executable part, and an optional exception-handling part.

What are the necessary parts of function declaration?

A function consist of two parts: Declaration: the function's name, return type, and parameters (if any) Definition: the body of the function (code to be executed)


2 Answers

This is called the 'receiver'. In the first case (h handler) it is a value type, in the second (s *GracefulServer) it is a pointer. The way this works in Go may vary a bit from some other languages. The receiving type, however, works more or less like a class in most object-oriented programming. It is the thing you call the method from, much like if I put some method A inside some class Person then I would need an instance of type Person in order to call A (assuming it's an instance method and not static!).

One gotcha here is that the receiver gets pushed onto the call stack like other arguments so if the receiver is a value type, like in the case of handler then you will be working on a copy of the thing you called the method from meaning something like h.Name = "Evan" would not persist after you return to the calling scope. For this reason, anything that expects to change the state of the receiver needs to use a pointer or return the modified value (gives more of an immutable type paradigm if you're looking for that).

Here's the relevant section from the spec; https://golang.org/ref/spec#Method_sets

like image 83
evanmcdonnal Avatar answered Sep 18 '22 15:09

evanmcdonnal


It means ServeHTTP is not a standalone function. The parenthesis before the function name is the Go way of defining the object on which these functions will operate. So, essentially ServeHTTP is a method of type handler and can be invoked using any object, say h, of type handler.

h.ServeHTTP(w, r) 

They are also called receivers. There are two ways of defining them. If you want to modify the receiver use a pointer like:

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

If you dont need to modify the receiver you can define the receiver as a value like:

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

This example from Go playground demonstrates the concept.

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) 

The output of the above program is :

&{0 0} &{0 0} &{5 7} 
like image 37
Abhishek Nalin Avatar answered Sep 17 '22 15:09

Abhishek Nalin