func<\/strong> keyword and the function name. The return_values come at the last.<\/p>\n\n\n\nAlso, let’s understand more differences between a function and a method. There are some important differences between them. Below is the signature of a function<\/p>\n\n\n\n
Function:<\/strong><\/p>\n\n\n\nfunc some_func_name(arguments) return_values<\/code><\/pre>\n\n\n\nWe have already seen the signature of a method<\/p>\n\n\n\n
Method:<\/strong><\/p>\n\n\n\nfunc (receiver receiver_type) some_func_name(arguments) return_values<\/code><\/pre>\n\n\n\nFrom the above signature, it is clear that the method has a receiver argument. This is the only difference between function and method, but due to it they differ in terms of functionality they offer<\/p>\n\n\n\n
- A function can be used as first-order objects and can be passed around while methods cannot.<\/li><\/ul>\n\n\n\n
- Methods can be used for chaining on the receiver while function cannot be used for the same.<\/li><\/ul>\n\n\n\n
- There can exist different methods with the same name with a different receiver, but there cannot exist two different functions with the same name in the same package.<\/li><\/ul>\n\n\n\n
<\/span>Methods on Structs<\/strong><\/span><\/h1>\n\n\n\nGolang is not an object-oriented language. It doesn’t support type inheritance, but it does allow us to define methods on any custom type including structs. Since struct is a named collection of fields and methods can also be defined on it. As such struct in golang can be compared to a class in Object-Oriented Languages.<\/p>\n\n\n\n
Let’s see an example of method on struct<\/p>\n\n\n\n
package main\n\nimport \"fmt\"\n\ntype employee struct {\n name string\n age int\n salary int\n}\n\nfunc (e employee) details() {\n fmt.Printf(\"Name: %s\\n\", e.name)\n fmt.Printf(\"Age: %d\\n\", e.age)\n}\n\nfunc (e employee) getSalary() int {\n return e.salary\n}\n\nfunc main() {\n emp := employee{name: \"Sam\", age: 31, salary: 2000}\n emp.details()\n fmt.Printf(\"Salary %d\\n\", emp.getSalary())\n}<\/code><\/pre>\n\n\n\nOutput<\/strong><\/p>\n\n\n\nName: Sam\nAge: 31\nSalary 2000<\/code><\/pre>\n\n\n\nNotice that the receiver is available inside the method and fields of the receiver can be accessed inside the method. <\/p>\n\n\n\n
Can field of the receiver also be changed inside the method?<\/p>\n\n\n\n
Let’s see that<\/p>\n\n\n\n
package main\n\nimport \"fmt\"\n\ntype employee struct {\n name string\n age int\n salary int\n}\n\nfunc (e employee) setNewName(newName string) {\n e.name = newName\n}\n\nfunc main() {\n emp := employee{name: \"Sam\", age: 31, salary: 2000}\n emp.setNewName(\"John\")\n fmt.Printf(\"Name: %s\\n\", emp.name)\n}<\/code><\/pre>\n\n\n\nOutput<\/strong><\/p>\n\n\n\nName: Sam<\/code><\/pre>\n\n\n\nA method setNewName is defined on the employee struct in the above code. In this method, we update the name of the employee like this<\/p>\n\n\n\n
e.name = newName<\/code><\/pre>\n\n\n\nAfter setting the new name when we print the employee name again in the main function, we see that the old name “Sam” is printed instead of “John”. This happens because method is defined on a value receiver<\/p>\n\n\n\n
func (e employee) setNewName(newName string)<\/code><\/pre>\n\n\n\nSince the method is defined on a value receiver when the method is called a copy of the receiver is made and that copy of the receiver is available inside the method. Since it is a copy, any changes made to the value receiver is not visible to the caller. That is why it prints the old name “Sam” instead of “John”. Now the question which comes to the mind whether there is any way to fix this. And the answer is yes, and this is where pointer receivers come into the picture.<\/p>\n\n\n\n
<\/span>Method on a Pointer Receiver<\/strong><\/span><\/h1>\n\n\n\nIn the above example we saw a method on a value receiver. Any change made to a value receiver is not visible to the caller. Methods can also be defined on a pointer receiver. Any change made to the pointer receiver will be visible to the caller. Let’s see an example<\/p>\n\n\n\n
package main\n\nimport \"fmt\"\n\ntype employee struct {\n name string\n age int\n salary int\n}\n\nfunc (e *employee) setNewName(newName string) {\n e.name = newName\n}\n\nfunc main() {\n emp := &employee{name: \"Sam\", age: 31, salary: 2000}\n emp.setNewName(\"John\")\n fmt.Printf(\"Name: %s\\n\", emp.name)\n}<\/code><\/pre>\n\n\n\nOutput<\/strong><\/p>\n\n\n\nName: John<\/code><\/pre>\n\n\n\nIn above program, we defined the method setNewName <\/strong>on a pointer receiver<\/p>\n\n\n\nfunc (e *employee) setNewName(newName string)<\/code><\/pre>\n\n\n\nThen we created an employee pointer and called the setNewName <\/strong>method <\/strong>on it. We see that the changes made to the employee pointer inside the setNewName <\/strong>are visible to the caller and it prints the new name.<\/p>\n\n\n\nIs it necessary to create the employee pointer to call a method with a pointer receiver? No, it is not. The method can be called on the employee instance and the language will take care of it to correctly pass it as a pointer to the method. This flexibility is provided by the language.<\/p>\n\n\n\n
Let’s see an example<\/p>\n\n\n\n
package main\n\nimport \"fmt\"\n\ntype employee struct {\n name string\n age int\n salary int\n}\n\nfunc (e *employee) setNewName(newName string) {\n e.name = newName\n}\n\nfunc main() {\n emp := employee{name: \"Sam\", age: 31, salary: 2000}\n emp.setNewName(\"John\")\n\n fmt.Printf(\"Name: %s\\n\", emp.name)\n\n (&emp).setNewName(\"Mike\")\n fmt.Printf(\"Name: %s\\n\", emp.name)\n}<\/code><\/pre>\n\n\n\nOutput<\/strong><\/p>\n\n\n\nName: John\nName: Mike<\/code><\/pre>\n\n\n\nWe see in the above program that even if a method is defined on a pointer receiver but we are calling the method with a non-pointer employee instance<\/p>\n\n\n\n
emp.setNewName(\"John\")<\/code><\/pre>\n\n\n\nBut the language passes the receiver as a pointer and therefore the changes are visible to the caller.<\/p>\n\n\n\n
Even this way of calling is valid<\/p>\n\n\n\n
(&emp).setNewName(\"Mike\")<\/code><\/pre>\n\n\n\nNow, how about the other way around. If a method is defined on a value receiver, can the method be called with a pointer of the receiver? <\/p>\n\n\n\n
Yes, even this is valid and the language takes care of passing the argument correctly as value receiver irrespective of whether the method was called on a pointer or normal struct. <\/p>\n\n\n\n
Let’s see an example<\/p>\n\n\n\n
package main\n\nimport \"fmt\"\n\ntype employee struct {\n name string\n age int\n salary int\n}\n\nfunc (e employee) setNewName(newName string) {\n e.name = newName\n}\n\nfunc main() {\n emp := employee{name: \"Sam\", age: 31, salary: 2000}\n emp.setNewName(\"John\")\n\n fmt.Printf(\"Name: %s\\n\", emp.name)\n (&emp).setNewName(\"Mike\")\n\n fmt.Printf(\"Name: %s\\n\", emp.name)\n emp2 := &employee{name: \"Sam\", age: 31, salary: 2000}\n emp2.setNewName(\"John\")\n fmt.Printf(\"Name: %s\\n\", emp2.name)\n}<\/code><\/pre>\n\n\n\nOutput<\/strong><\/p>\n\n\n\nName: Sam\nName: Sam\nName: Sam<\/code><\/pre>\n\n\n\nDo note here since in all three cases, the setNewName<\/strong> method had a value receiver hence changes are not visible to the caller as the value is passed as a copy. It prints the old name in all three cases<\/p>\n\n\n\nTo summarize what we learnt above<\/p>\n\n\n\n
- If a method has a value receiver it supports calling of that method with both value and pointer receiver<\/li><\/ul>\n\n\n\n