is the receiver of the method in go the difference between a value or a pointer?

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Reference article: http://studygolang.com/articles/1113

The following issues are expected to be resolved

Suppose there are two methods, the recipient of a method is a pointer type, and the recipient of a method is a value type, then:

    • What is the difference between these two methods for variables of value types and for variables of pointer types?
    • If these two methods are intended to implement an interface, can both methods be called?
    • If the method is embedded in other structures, what are the above two things?

Variables of value type and pointer types

Declare a struct first:

typestruct {    string}func (t T) M1() {    "name1"}func (t *T) M2() {    "name2"}

The recipient of M1 () is a value type T, the recipient of M2 () is a value type *t, and two methods change the name value.

The following declares a T variable of type and calls M1() and M2() .

    t1 := T{"t1"}    fmt.Println("M1调用前:", t1.Name)    t1.M1()    fmt.Println("M1调用后:", t1.Name)    fmt.Println("M2调用前:", t1.Name)    t1.M2()    fmt.Println("M2调用后:", t1.Name)

The output is:

M1调用前: t1M1调用后: t1M2调用前: t1M2调用后: name2

Let's guess what go will do with it.

Let's make a pact: the receiver can be thought of as the first parameter of the function, that is: func M1(t T) func M2(t *T) Go is not an object-oriented language, so it may be biased to understand that it looks like object-oriented syntax.

When called t1.M1() , the M1(t1) argument and the row parameter are both type T and can be accepted. At this point the T in M1 () is only a copy of the value of T1, so the modification of M1 () does not affect T1.

When called t1.M2() = = M2(t1) , this is the type of T passed to the *t type, go may take T1 address to pass in: M2(&t1) . So the modification of M2 () can affect T1.

Variables of type T are owned by both methods.

The following declares a *T variable of type and calls M1() and M2() .

    t2 := &T{"t2"}    fmt.Println("M1调用前:", t2.Name)    t2.M1()    fmt.Println("M1调用后:", t2.Name)    fmt.Println("M2调用前:", t2.Name)    t2.M2()    fmt.Println("M2调用后:", t2.Name)

The output is:

M1调用前: t2M1调用后: t2M2调用前: t2M2调用后: name2

t2.M1()= = M1(t2) , t2 is the pointer type, takes the value of T2 and copies a copy to M1.

t2.M2()= = M2(t2) is a pointer type and does not need to be converted.

Variables of type *t are also owned by these two methods.

What happens when I pass it to the interface?

Declare an interface first

type Intf interface {    M1()    M2()}

Use:

    var t1 T = T{"t1"}    t1.M1()    t1.M2()    var t2 Intf = t1    t2.M1()    t2.M2()

Error:

./main.go:9: cannot use t1 (typeastypein assignment:    notmethod has pointer receiver)

var t2 Intf = t1This line is an error.

T1 is a M2 () method, but why is it not passed on to T2 simultaneous?

T1 is a value type, assigning a value to T2 is a copy of a value instead of a pointer, assuming T1 can be assigned to T2, T2. M2 () Modify the value of Name is also a modified copy of the variable, can not affect the T1, that T1 assigned to T2 What is the point? So this assignment is not allowed.

When the var t2 Intf = t1 modification to var t2 Intf = &t1 compile through, at this time T2 obtained is the address of T1, t2.M2() the modification can affect the T1.

If you declare a method, the pass of the func f(t Intf) parameter is the same as the direct assignment above.

Nested types

Declare a type S, embed T in

type S struct {    T}

Use the following example to test:

    t1 := T{"t1"}    s := S{t1}    fmt.Println("M1调用前:", s.Name)    s.M1()    fmt.Println("M1调用后:", s.Name)    fmt.Println("M2调用前:", s.Name)    s.M2()    fmt.Println("M2调用后:", s.Name)    fmt.Println(t1.Name)

Output:

M1调用前: t1M1调用后: t1M2调用前: t1M2调用后: name2t1

If T is embedded in S, then the methods and properties that T owns are also owned, but the receiver is not s but T.

So s.M1() it M1(t1) 's equivalent instead of M1(s) .

The last T1 value does not change, because we embed the T type, so S{t1} the time is to copy the T1 copies.

What if we assign S to the Intf interface?

    var intf Intf = s    intf.M1()    intf.M2()

Error:

cannot use s (typeastypein assignment:    notmethod has pointer receiver)

is still a problem with M2 () because S is still a value type at this time.

var intf Intf = &sSo the compiler passed, if the intf.M2() value changed in the Name, s.Name was changed, but t1.Name still unchanged, because now T1 and S have no contact.

Try embedding *t below:

type S struct {    *T}

When using this:

    t1 := T{"t1"}    s := S{&t1}    fmt.Println("M1调用前:", s.Name)    s.M1()    fmt.Println("M1调用后:", s.Name)    fmt.Println("M2调用前:", s.Name)    s.M2()    fmt.Println("M2调用后:", s.Name)    fmt.Println(t1.Name)

The only difference is that the value of the last T1 is changed, because we are copying pointers.

Then assign the value to the interface to try:

    var intf Intf = s    intf.M1()    intf.M2()    fmt.Println(s.Name)

Compile without error. What we pass to intf here is the value type instead of the pointer, why can we pass it?

When you copy S, T is the pointer type, so when you call M2 (), you pass in a pointer.

var intf Intf = &sThe effect is the same as above.

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.