Introduction to Methods
So far in this course, you have studied and used functions. This lesson brings a new concept of Go similar to functions but slightly different, i.e., methods.
We'll cover the following...
What is a method?
Structs look like a simple form of classes, so an OO programmer might ask, where are the methods of the class? Again, Go has a concept with the same name and roughly the same meaning. A Go method is a function that acts on a variable of a certain type, called the receiver. Therefore, a method is a special kind of function.
Note: A method acting on a variable in Go is similar to the object of a class calling its function in other OO languages, using a
.
selector, e.g.,object.function()
.
The receiver type can be (almost) anything, not only a struct type. Any type can have methods, even a function type or alias types for int, bool, string, or array. However, the receiver cannot be an interface type since an interface is an abstract definition and a method is the implementation. Trying to do so generates the compiler error: invalid receiver type.
Lastly, a method cannot be a pointer type, but it can be a pointer to any of the allowed types. The combination of a (struct) type and its methods is the Go equivalent of a class in OO. One important difference is that the code for the type and the methods binding to it are not grouped together. They can exist in different source files; the only requirement is that they have to be in the same package.
The collection of all the methods on a given type T
(or *T
) is called the method set of T
(or *T
).
Methods are functions, so again, there is no method overloading, which means for a given type, there is only one method with a given name. However, based on the receiver type, there is overloading. A method with the same name can exist on two or more different receiver types, e.g., this is allowed in the same package:
func (a *denseMatrix) Add(b Matrix) Matrix
func (a *sparseMatrix) Add(b Matrix) Matrix
An alias of a certain type can’t redefine the methods defined on that type because an alias is the same as the original type. However, a new type based on a type can redefine these methods.
This is illustrated in the following example:
package main import "fmt" type S struct { a int } type SType S // New type type SAlias = S // Alias type IntType int // New type type IntAlias = int // Alias func (recv S) print() { // function for type defined on type S fmt.Printf("%t: %[1]v\n", recv) } func (recv SType) print() { // function for type defined on the basis of S fmt.Printf("%t: %[1]v\n", recv) } // func (recv SAlias) print() { // <-- error: S.print redeclared in this block previous declaration at ./struct_method.go:15:6 // fmt.Printf("%t: %[1]v\n", recv) // } func (recv IntType) print() { // function for type defined on type on the basis of int fmt.Printf("%t: %[1]v\n", recv) } // func (recv IntAlias) print() { // <-- error: cannot define new methods on non-local type int // fmt.Printf("%t: %[1]v\n", recv) // } func main(){ a := S{10} a.print() // calling function from line 13 b := SType{20} b.print() // calling function from line 16 c := SAlias{30} c.print() // calling function from line 13 d := IntType(40) d.print() // calling function from line 24 // e := IntAlias(50) <-- error: e.print undefined (type int has no field or method print) // e.print() }
Click the RUN button and wait for the terminal to start. Type go run main.go
and press ENTER. In case you make any changes to the file, you ...