The go language inside receiver should be defined as a value or a pointer

Source: Internet
Author: User
Tags subq
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.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.