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