SoFunction
Updated on 2025-03-05

Introduction to the difference between copy transfer of structure method in Go language and participating in pointer transfer parameters

The difference between GO language structure method and structure pointer method

First, I defined three interfaces, a structure and three methods:

type DeptModeA interface {
Name() string
SetName(name string)
}
type DeptModeB interface {
Relocate(building string, floor uint8)
}
type Dept struct {
name string
building string
floor uint8
Key string
}
func (self Dept) Name() string {
return 
}
func (self Dept) SetName(name string) {
 = name
}
func (self *Dept) Relocate(building string, floor uint8) {
 = building
 = floor
}

Then I wrote some test code:

dept1 :=
Dept{
name: "MySohu",
building: "Internet",
floor: 7}
switch v := interface{}(dept1).(type) {
case DeptModeFull:
("The dept1 is a DeptModeFull.\n")
case DeptModeB:
("The dept1 is a DeptModeB.\n")
case DeptModeA:
("The dept1 is a DeptModeA.\n")
default:
("The type of dept1 is %v\n", v)
}
deptPtr1 := &dept1
if _, ok := interface{}(deptPtr1).(DeptModeFull); ok {
("The deptPtr1 is a DeptModeFull.\n")
}
if _, ok := interface{}(deptPtr1).(DeptModeA); ok {
("The deptPtr1 is a DeptModeA.\n")
}
if _, ok := interface{}(deptPtr1).(DeptModeB); ok {
("The deptPtr1 is a DeptModeB.\n")
}

Printed content:

The dept1 is a DeptModeA.

The deptPtr1 is a DeptModeFull.

The deptPtr1 is a DeptModeA.

The deptPtr1 is a DeptModeB.

Assuming T is a struct, then Go follows the following principles:

  • T's method set only has the T Receiver method.
  • The *T method set contains all methods (T + *T).

So your example above dept1 should be the method of having: Name and SetName

And &dept1 has methods: Name, SetName and Relocate

This is what you need to pay attention to when designing methods in Go.

The difference between copy transfer of structure method in Go language and participating in pointer transfer parameters

Let's take a look at an example:

package main
import (
 "fmt"
)
type B struct {
 Name string
}
func(b B) Test1() {
 ("Test1 addr:%p\n", &b)
 ("Test1 name:%s\n", )
  = "john"
}
func(b *B) Test2() {
 ("Test2 addr:%p\n", b)
 ("Test2 name:%s\n", )
  = "john"
}
func main() {
 b := B{}
 b.Test1()
 b.Test1()
 b.Test2()
 b.Test2()
}

The results after execution are as follows:

Test1 addr:0xc42000e1e0
Test1 name:
Test1 addr:0xc42000e1f0
Test1 name:
Test2 addr:0xc42000e1d0
Test2 name:
Test2 addr:0xc42000e1d0
Test2 name:john

You can see that the address of the b structure is printed in Test1, but there is no change in Test2. This means that every call to Test1 is a copy (copy) of the incoming structure b. Any changes to the internal variables in Test1 will be invalid (because the next time you access is the new copy of the b structure). When the Test2 method passes parameters as a pointer, each time it is passed in, the pointer of the b structure, pointing to the same structure, so the address has not changed, and when the internal variables are changed, the content of the b structure is changed.

This difference in Go language may be a pitfall in OOP design. In Go language, if you want to implement OOP design, you use the Test2 writing method when encapsulating it.

Summarize

The above is the entire content of this article. I hope that the content of this article has certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support.