Go methods and recipients

Posted by hkay1 on Tue, 08 Feb 2022 23:55:41 +0100

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

  1. The value in the receiver needs to be modified

  2. The receiver is a large object with high copy cost

  3. To ensure consistency, if a method uses a pointer receiver, other methods should also use a pointer receiver.

  4. 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()
}

Topics: Go