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 mainimport "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 mainimport "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 mainimport "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}