Go - Methods
A method is a function with a special receiver parameter.
Declaration
- Methods can be defined on types that are defined in the same package
- They cannot be defined for built-in types or types in other packages
- The receiver associates the method with the receiver’s base type
- The receiver is specified with a parameter preceding the method name
- The receiver must be a type or a pointer to a type
go
// By convention a single letter is used for the receiver's parameter.
func (r ReceiverType) MethodName() {
// Method implementation
}
Value Receiver
go
package main
import "fmt"
// A custom type.
type MyInt int
// Go does not have classes, however we can define methods on types.
// When using a value receiver a copy is passed.
// A value receiver is used when the method doesn't modify the value.
func (i MyInt) Square() int {
return int(i * i) // Convert MyInt to int
}
func main() {
var n MyInt = 2
fmt.Println(n) // 2
// Call a method.
squared := n.Square()
fmt.Println(squared) // 4
// A pointer to the variable.
p := &n // *MyInt
// A method with a value receiver can be called on a pointer.
p.Square()
// Equivalent to
(*p).Square()
}
Pointer Receiver
go
package main
import "fmt"
type MyInt int
// A pointer receiver allows the method to modify the receiver's value.
// It can also be used for performace optimization to avoid copying a large value
// on each method call even if the method does not modify the receiver.
func (i *MyInt) Increment() {
*i++ // Modify the value
}
// For consistency if a method uses a pointer receiver we define
// all the other methods too with a pointer even if they don't modify the value.
func (i *MyInt) Square() int {
return int(*i * *i) // Convert MyInt to int
}
func main() {
var n MyInt
fmt.Println(n) // 0 (zero value)
// Call a method that modifies the value.
// Methods with a pointer receiver can be called with a value or a pointer.
n.Increment()
// Equivalent to
(&n).Increment()
fmt.Println(n) // 2 (incremented twice)
fmt.Println(n.Square()) // 4
}
Method Value & Expression
go
package main
import "fmt"
type MyInt int
// Method with value receiver.
func (i MyInt) Square() int {
return int(i * i)
}
// Method with pointer receiver.
func (i *MyInt) Increment() {
*i = *i * 2
}
func main() {
a := MyInt(4)
// A method value is created by referencing a method
// on a specific instance of a type.
square := a.Square // Method value
// A method value captures the receiver value.
// It allows calling the method without specifying the receiver.
fmt.Println(square()) // 16
// A method expression is created by referencing a method on a type.
Square := MyInt.Square // Method expression
// A method expression converts the method into a function
// that takes the receiver as its first argument.
// It allows using the method as a general function with
// different receiver values.
fmt.Println(Square(a)) // 16
increment := a.Increment // Method value
Increment := (*MyInt).Increment // Method expression
increment() // Equivalent to a.Increment()
fmt.Println(a) // 5
Increment(&a) // Equivalent to (&a).Increment()
fmt.Println(a) // 6
}