Summary of variable differences between value type/pointer type in Golang

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

Objective

Value types: All types, such as int, float, bool, and string, are value types that use variables of these types to point directly to a value that exists in memory, and the value of a value type's variable is stored in the stack. When using equal sign = Assigning the value of a variable to another variable, such as J = i, is actually a copy of the value of I in memory. The memory address of the variable I can be obtained by &i

Pointer type: Simply speaking, the pointer type of the go language is the same as the pointer type usage for C/s + +, except for security reasons, the Go language adds some restrictions, including the following:

    • Different types of pointers cannot be converted to each other, such as *int, Int32, and Int64
    • Any normal pointer type *t and UINTPTR cannot be converted to each other
    • Pointer variables cannot be operated on, such as + + in C + +,--operations

The following will give you a detailed description of the Golang in the value type/pointer type of the variables of some differences, the following words do not say, come together to see the detailed introduction.

Variables of value type and pointer types

Declare a struct first:

Type T struct {Name string}func (T T) M1 () {t.name = "name1"}func (t *t) M2 () {t.name = "name2"}

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

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

T1: = t{"T1"} fmt. Println ("M1 called before:", T1. Name) t1. M1 () fmt. Println ("M1 after Call:", T1. Name) fmt. Println ("M2 called before:", T1. Name) t1. M2 () fmt. Println ("M2 after Call:", T1. Name)

The output is:

Before M1 call: T1

After M1 call: T1

Before M2 call: T1

After M2 call: 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. In this case M1() , T is just a copy of the value of T1, so M1() the modification 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 M2()  the changes can affect T1.

Types of variables are owned by both methods.

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

T2: = &t{"T2"} fmt. Println ("M1 called before:", T2. Name) T2. M1 () fmt. Println ("M1 after call:", T2. Name) fmt. Println ("M2 called before:", T2. Name) T2. M2 () fmt. Println ("M2 after call:", T2. Name)

The output is:

Before M1 call: T2

After M1 call: T2

Before M2 call: T2

After M2 call: 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), which are pointer types and do 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 (type T) as type Intf in assignment:

T does not implement Intf (M2 method has pointer receiver)

var t2 Intf = t1This line is an error.

T1 There is a M2()  way, but why pass to T2 simultaneous not pass?

Simply put, according to the theory of the interface: Pass the "assignment" of the object must implement the interface requirements of the method, and T1 is not implemented M2() , T1 pointer implementation M2() . In addition, like the C language, the function name itself is the pointer

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 fun, the arguments are passed in the same way as the c f(t Intf) 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 called Before:", S.name)  s.m1 ()  FMT. Println ("M1 called after:", S.name)  FMT. Println ("M2 called Before:", S.name)  s.m2 ()  FMT. Println ("M2 called after:", S.name)  FMT. Println (t1. Name)

Output:

Before M1 call: T1

After M1 call: T1

Before M2 call: T1

After M2 call: name2

T1

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} is a copy of the T1.

What if we assign S to the Intf interface?

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

Error:

cannot use s (type S) as type Intf in assignment: S does not implement Intf (M2 method has pointer receiver)

This is still a M2() problem, because S is still a value type.

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 called Before:", S.name)  s.m1 ()  FMT. Println ("M1 called after:", S.name)  FMT. Println ("M2 called Before:", S.name)  s.m2 ()  FMT. Println ("M2 called after:", S.name)  FMT. Println (t1. Name)

Before M1 call: T1

After M1 call: T1

Before M2 call: T1

After M2 call: name2

Name2

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 i ntf. 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 copying S, T is the pointer type, so the call M2()  is passed in a pointer.

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

http://www.pdfxs.com/search?q=APAK-113

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.