methods
Method declaration: a method is declared by putting a variable before the name of a function. This additional argument attaches the function to the type, which defines an exclusive method for that type.
The additional parameter p in the following code is called the receiver for the method.
package geometry
import "math"
type Point struct{ X, Y float64 }
// traditional function
func distance(p, q Point) float64 {
return math.Hypot(q.X-p.X, q.Y-p.Y)
}
// same thing, but as a method of the Point type
func (p Point) distance(q Point) float64 {
return math.Hypot(q.X-p.X, q.Y-p.Y)
}
Copy the code
Method call:
p := Point{1.2}
q := Point{4.6}
fmt.Println(Distance(p, q)) // "5", function call
fmt.Println(p.Distance(q)) // "5", method call
Copy the code
Pointer object based methods
We can declare methods with Pointers instead of objects
func (p *Point) ScaleBy(factor float64) {
p.X *= factor
p.Y *= factor
}
Copy the code
When declaring methods, a type name is not allowed in the sink if it is itself a pointer
type P *int
func (P) f(a) { / *... * / } // compile error: invalid receiver type
Copy the code
Call the pointer type method (*Point).scaleby by providing a pointer to Point
// plan1
r := &Point{1.2}
r.ScaleBy(2)
fmt.Println(*r) {2, 4} "/ /"
// plan2
p := Point{1.2}
pptr := &p
pptr.ScaleBy(2)
fmt.Println(p) {2, 4} "/ /"
//plan3
p := Point{1.2}
(&p).ScaleBy(2)
fmt.Println(p) {2, 4} "/ /"
Copy the code
However, the latter two methods are somewhat unwieldy. Fortunately, the go language itself helps us in places like this. If the sink p is a variable of type Point, and the method requires a Point pointer as the sink, we can write it briefly as follows:
p.ScaleBy(2)
Copy the code
The compiler implicitly helps us call the ScaleBy method with &p. This shorthand applies only to “variables”, including struct fields such as p.X and elements in array and slice such as perim[0]. We cannot call pointer methods from a receiver that cannot fetch an address, such as the memory address of a temporary variable:
Point{1.2}.ScaleBy(2) // compile error: can't take address of Point literal
Copy the code