Go - Use methods and interfaces in Go (I)
Source: Use methods and interfaces in Go
Methods in Go
A method in Go is a special type of function with a simple difference: you have to include an extra parameter before the function name. This additional parameter is known as the receiver
Declare methods
func (variable type) MethodName(parameters ...) {
// method functionality
}
Before you can declare a method, you have to create a struct
type triangle struct {
size int
}
// method for the triangle struct
func (t triangle) perimeter() int {
return t.size * 3
}
t := triangle{3}
fmt.Println("Perimeter:", t.perimeter()) // Perimeter: 9
Pointers in methods
If you need to update a variable or, if the argument is too big, you might want to avoid copying. In these cases use pointers to pass the address of a variable.
func (t *triangle) doubleSize() {
t.size *= 2
}
t := triangle{3}
fmt.Println("Size:", t.size) // Size: 3
t.doubleSize()
fmt.Println("Size:", t.size) // Size: 6
Declare methods for other types
You can’t define a struct from a type that belongs to another package. Therefore, you can’t create a method on a basic type, such as a string. Nonetheless, you can use a hack to create a custom type from a basic type and then use it as if it were the basic type.
type upperstring string
func (s upperstring) Upper() string {
return strings.ToUpper(string(s))
}
s := upperstring("Learning Go!")
fmt.Println(s) // Learning Go!
fmt.Println(s.Upper()) // LEARNING GO!
Embed methods
You can call methods of the embedded struct even if the receiver is different.
type coloredTriangle struct {
triangle // embed struct
color string
}
t := coloredTriangle{triangle{3}, "blue"}
mt.Println("Size:", t.size) // Size: 3
Overload methods
You’re allowed to have a method with the same name as long as it’s specific to the receiver you want to use
// we overlap the perimeter method defined for triangle struct
// now we define it for the coloredTriangle receiver
func (t coloredTriangle) perimeter() int {
return t.size * 3 * 2
}
t := coloredTriangle{triangle{3}, "blue"}
fmt.Println("Size:", t.size)
fmt.Println("Perimeter (colored)", t.perimeter()) // Perimeter (colored) 18
// We can still access to the triangle perimeter method
fmt.Println("Perimeter (normal)", t.triangle.perimeter()) // Perimeter (normal) 9
Encapsulation in methods
In Go, you need to use only a capitalized identifier to make a method public and an uncapitalized identifier to make a method private.
- public: capitalized
- private: uncapitalized
package geometry
type Triangle struct {
size int
}
// private method
func (t *Triangle) doubleSize() {
t.size *= 2
}
// public method
func (t *Triangle) SetSize(size int) {
t.size = size
}