Go methods and recipients
The Method in Go language is a function that acts on a specific type of variable. This particular type of variable is called a Receiver. The concept of Receiver is similar to this or self in other languages.
The definition format of the method is as follows:
func (Receiver variable receiver type) Method name(parameter list) (Return parameters) { Function body }
Among them,
- Receiver variable: when naming the parameter variable name in the receiver, it is officially recommended to use the lowercase of the initial letter of the receiver type name instead of naming such as self and this. For example, the receiver variable of Person type should be named p, and the receiver variable of Connector type should be named c, etc.
- Receiver type: the receiver type is similar to the parameter, and can be pointer type and non pointer type.
- Method name, parameter list and return parameter: the specific format is the same as the function definition.
for instance:
//Person structure type Person struct { name string age int8 } //NewPerson constructor func NewPerson(name string, age int8) *Person { return &Person{ name: name, age: age, } } //Dream Person's method of dreaming func (p Person) Dream() { fmt.Printf("%s My dream is to learn English well Go Language!\n", p.name) } func main() { p1 := NewPerson("princeling", 25) p1.Dream() }
The difference between methods and functions is that functions do not belong to any type, and methods belong to specific types.
Receiver of pointer type
The receiver of pointer type is composed of a pointer of a structure. Due to the characteristics of the pointer, any member variable of the receiver pointer is modified when calling the method, and the modification is effective after the end of the method. This approach is very close to this or self in object-oriented in other languages. For example, we add a SetAge method for Person to modify the age of the instance variable.
// SetAge sets the age of p // Pointer receiver use func (p *Person) SetAge(newAge int8) { p.age = newAge }
Call this method:
func main() { p1 := NewPerson("princeling", 25) fmt.Println(p1.age) // 25 p1.SetAge(30) fmt.Println(p1.age) // 30 }
Recipient of value type
When the method acts on the value type receiver, the Go language will copy the receiver's value when the code runs. In the method of value type receiver, the member value of the receiver can be obtained, but the modification operation is only for the copy, and the receiver variable itself cannot be modified.
// SetAge2 sets the age of p // Use value receiver func (p Person) SetAge2(newAge int8) { p.age = newAge } func main() { p1 := NewPerson("princeling", 25) p1.Dream() fmt.Println(p1.age) // 25 p1.SetAge2(30) // (*p1).SetAge2(30) fmt.Println(p1.age) // 25 }
When should a pointer type receiver be used
-
The value in the receiver needs to be modified
-
The receiver is a large object with high copy cost
-
To ensure consistency, if a method uses a pointer receiver, other methods should also use a pointer receiver.
-
package main import "fmt" //A method is a function that acts on a specific type //Method definition instance // Person is a structure type Person struct { name string age int8 } //NewPerson is a constructor of type Person func NewPerson(name string ,age int8) *Person{ return &Person{ name: name, age: age, } } //Dream is a method defined for the Person type func (p Person)Dream() { fmt.Printf("%s \n",p.name) } //SetAge is a method of modifying age using pointer type func (p *Person) SetAge(newage int8) { p.age = newage } //SetAge2 is a method that uses value recipients to modify age func (p Person) SetAge2(newage int8) { p.age = newage } func main() { p1 := NewPerson("Shahe Naza",int8(18)) p1.Dream() //(*p1).Dream()//Go language will automatically recognize the type of P1 //Call the method to modify the age fmt.Println(p1.age) p1.SetAge(int8(20)) fmt.Println(p1.age) p1.SetAge2(int8(30)) fmt.Println(p1.age) }
Add method of any type
In Go language, the type of receiver can be any type, not just a structure, and any type can have methods. For example, we can use the type keyword to define a new custom type based on the built-in int type, and then add methods for our custom type.
//MyInt defines int as a custom MyInt type type MyInt int //SayHello adds a SayHello method to MyInt func (m MyInt) SayHello() { fmt.Println("Hello, I am a int. ") } func main() { var m1 MyInt m1.SayHello() //Hello, I'm an int. m1 = 100 fmt.Printf("%#v %T\n", m1, m1) //100 main.MyInt }
Note: non local types (not defined in this package) cannot define methods, that is, we cannot define methods for the types of other packages.
package main import "fmt" //Add method for any type //Build our own type based on the built-in basic type type myInt int func (m myInt) sayHi() { fmt.Println("hi") } func main() { var m1 myInt m1 = 100 m1.sayHi() }