Search⌘ K
AI Features

Introduction to Methods

Explore the concept of methods in Go, focusing on how methods act on receiver types including structs and aliases. Understand method syntax, receiver rules, method sets, and practical usage through examples. This lesson clarifies how Go implements object-oriented behavior without traditional classes and method overloading, helping you write more structured and idiomatic Go code.

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 ...