Golang Basics - Methods

Defining methods

Go is a little different from traditional object oriented languages in that there are no classes, only types. Methods can be defined on any type within the package in which it is defined.

type Vehicle struct{
        Model string
        Wheels int
}

// We can define methods on types
// 1  2          3
func (v Vehicle) isCar() bool {
        return v.Wheels == 4
}

bmw := Vehicle{
        Model: "BMW",
        Wheels: 4,
}

// And call the methods using the `.` operator
fmt.Println(bmw.isCar())
// true
  1. Methods are declared with the func keyword
  2. The type for which the method is being defined is declared before the function name (Vehicle), along with a reference (v) to the variable itself. This is known as the receiver of the method.
  3. The method definition, which follows the same pattern as a regular function definition.

Pointer receivers

Methods can defined on pointers to variables as well, and are actually essential if we need to modify the value of the method receiver.

Remember, in the post on pointers, we discussed that everything in Go is passed by value. This is true for methods as well. If we wanted to modify a struct using its method, we would not be able to. Using a pointer method, however, this is entirely possible:

// Let's define the `removeWheel` method on the `Vehicle` type
func (v Vehicle) removeWheel() {
        v.Wheels--
}

// and a similar method on the `*Vehicle` type
func (v *Vehicle) removeWheelForReal() {
        v.Wheels--
}

bike := Vehicle{
        Model: "Ducati",
        Wheels: 2,
}

// calling this method on bike does not modify its value
bike.removeWheel()

fmt.Println(bike.Wheels)
// 2

bikePtr := &bike
// The method on the pointer receiver modifies the value of `bike`
bikePtr.removeWheelForReal()

fmt.Println(bike.Wheels)
// 1

Defining methods on other types

Remember, methods can be defined on any type within the package, not just structs and struct pointers. If the type you want to define a method on doesn't exist in the package, you can use a type alias:

// define an alias to int
type incNum int

func (i incNum) increment() incNum {
        return i + 1
}

var i incNum
fmt.Println(i.increment())

📖 Read next: Interfaces


Liked this article? Share it on: