This is a creation in Article, where the information may have evolved or changed.
The go language inside receiver should be defined as a value or a pointer, such as
func (s *MyStruct) pointerMethod() { } // method on pointerfunc (s MyStruct) valueMethod() { } // method on value
Which is defined in a way that satisfies the requirements.
Let's give you a code example
package mainimport "fmt"type MyStruct struct { i1, i2, i3, i4 int }func (h * MyStruct) incI2() { h.i2++ }func (h MyStruct) incI3() { h.i3++ }func main() { h1 := MyStruct{0x1111, 0x2222, 0x3333, 0x4444} h2 := &h1 h1.i1 = 11111111 h1.incI2() h1.i1 = 22222222 h1.incI3() h1.i1 = 33333333 h2.incI2() h2.incI3() fmt.Printf("i2=%x, i3=%x\n", h1.i2, h2.i3)}
Run the result as
$ go build main.go && ./main i2=2224, i3=3333
You can see that I2 has been added two times, the value of i3 has not changed; The reason is that because the incI2 () method declares that receiver is a pointer, and IncI3 () is a value.
The FAQ has a solution, as a value and as a pointer to the difference. Https://golang.org/doc/faq#methods_on_values_or_pointers
The idea is simply that we think of receiver as a parameter to see if you need to pass a value or pass a pointer.
func pointerMethod(s *MyStruct) { } // passing parameter as pointerfunc valueMethod(s MyStruct) { } // passing parameter as value
Below is the attachment content; Look at how the specific code handles receiver as a value and as a pointer.
First as a pointer incI2
Caller's instructions are as follows
0x008a 00138 (/path/to/main.go:15) LEAQ "".h1+64(SP), AX 0x008f 00143 (/path/to/main.go:15) MOVQ AX, (SP) 0x0093 00147 (/path/to/main.go:15) PCDATA $0, $1 0x0093 00147 (/path/to/main.go:15) CALL "".(*MyStruct).incI2(SB)
See the instructions to the H1 address, to Ax, and then press the top of the stack, then call INC2.
See the code for callee (incI2)
0x0000 00000 (/path/to/main.go:7) TEXT "". (*mystruct). IncI2 (SB), $16-8 0x0000 00000 (/path/to/main.go:7) subq $16, SP 0x0004 00004 (/path/to/main.go:7) M OVQ BP, 8 (SP) 0x0009 00009 (/path/to/main.go:7) Leaq 8 (SP), BP 0x000e 00014 (/path/to/main.go:7) funcdata $ gclocals a36216b97439c93dafebe03e7f0808b5 (SB) 0x000e 00014 (/path/to/main.go:7) Funcdata $, GCLOCALS·33CDECCC CEBE80329F1FDBEE7F5874CB (SB) 0x000e 00014 (/path/to/main.go:7) movq "". H+24 (FP), AX 0x0013 00019 (/path/to/main. Go:7) Testb AL, (ax) 0x0015 00021 (/path/to/main.go:7) Movq 8 (AX), ax 0x0019 00025 (/path/to/main.go:7) movq AX, "". Autotmp_0 (SP) 0x001d 00029 (/path/to/main.go:7) movq "". H+24 (FP), CX 0x0022 00034 (/path/to/main.go:7) TESTB AL, (CX) 0x0024 00036 (/path/to/main.go:7) Incq ax 0x0027 00039 (/path/to/main.go:7) movq ax, 8 (CX) 0x002 b 00043 (/path/to/main.go:7) Movq 8 (SP), BP 0x0030 00048 (/path/to/main.go:7) ADDQ $16, SP 0x0034 00052 (/path/to/main.go:7) RET
Look again as value incI3
Caller's instructions are as follows
0x00a1 00161 (/path/to/main.go:17) MOVQ "".h1+64(SP), AX 0x00a6 00166 (/path/to/main.go:17) MOVQ "".h1+72(SP), CX 0x00ab 00171 (/path/to/main.go:17) MOVQ "".h1+80(SP), DX 0x00b0 00176 (/path/to/main.go:17) MOVQ "".h1+88(SP), BX 0x00b5 00181 (/path/to/main.go:17) MOVQ AX, (SP) 0x00b9 00185 (/path/to/main.go:17) MOVQ CX, 8(SP) 0x00be 00190 (/path/to/main.go:17) MOVQ DX, 16(SP) 0x00c3 00195 (/path/to/main.go:17) MOVQ BX, 24(SP) 0x00c8 00200 (/path/to/main.go:17) PCDATA $0, $1 0x00c8 00200 (/path/to/main.go:17) CALL "".MyStruct.incI3(SB)
See the instruction to the H1 member I1,i2,i3,i4 value, passed to AX,CX,DX,BX, then pressed into the stack, then call incI2, see and incI2 the difference is the value of H1 all through the stack passed to the incI3, equivalent to copy the H1 content, this is the value , the H1 made a copy, the contents of the copy into the IncI3, and the original H1 remain motionless.
See the code for callee (incI3)
0x0000 00000 (/path/to/main.go:8) TEXT "".MyStruct.incI3(SB), $16-32 0x0000 00000 (/path/to/main.go:8) SUBQ $16, SP 0x0004 00004 (/path/to/main.go:8) MOVQ BP, 8(SP) 0x0009 00009 (/path/to/main.go:8) LEAQ 8(SP), BP 0x000e 00014 (/path/to/main.go:8) FUNCDATA $0, gclocals·ff19ed39bdde8a01a800918ac3ef0ec7(SB) 0x000e 00014 (/path/to/main.go:8) FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB) 0x000e 00014 (/path/to/main.go:8) MOVQ "".h+40(FP), AX 0x0013 00019 (/path/to/main.go:8) MOVQ AX, ""..autotmp_1(SP) 0x0017 00023 (/path/to/main.go:8) INCQ AX 0x001a 00026 (/path/to/main.go:8) MOVQ AX, "".h+40(FP) 0x001f 00031 (/path/to/main.go:8) MOVQ 8(SP), BP 0x0024 00036 (/path/to/main.go:8) ADDQ $16, SP 0x0028 00040 (/path/to/main.go:8) RET
Comparing the implementation code of INCI2 and IncI3, it is clear to see that receiver is actually handled as a parameter, with the difference between the value and the pointer, and whether the parameter is the same as the value of the pass or the pointer.