Golang The various instantiation and assignment methods of struct, sometimes by value transfer, sometimes by pointer, are confusing, so I decided to sort it out and understand the whole thing. .
Define a structure first and explain it below with the code.
package mainimport "fmt"type Person struct { Name string Age int Descprtion string}
p instantiates a struct in the most conventional way, and the variable p gets a Person structure.
p := Person{} p.Name = "小明" fmt.Printf("p:%+v 变量地址:%p\n", p, &p) fmt.Println("===========") // result: // p:{Name:小明 Age:0 Descprtion:} 变量地址:0xc000078480 // ===========
The variable p1 is assigned by p. Since the Golang language is value transfer
, after the assignment, the modification to p1 will not It will not affect p;
It can also be seen from the first output that Golang’s assignment does not have a copy on write mechanism like PHP variable assignment. .
p1 := p fmt.Printf("p1:%+v 变量地址:%p\n", p1, &p1) // 不存在写时复制 p1.Name = "小明p1" fmt.Printf("p:%+v 变量地址:%p\n", p, &p) fmt.Printf("p1:%+v 变量地址:%p\n", p1, &p1) fmt.Println("===========") // result: // p1:{Name:小明 Age:0 Descprtion:} 变量地址:0xc0000784e0 // p:{Name:小明 Age:0 Descprtion:} 变量地址:0xc000078480 // p1:{Name:小明p1 Age:0 Descprtion:} 变量地址:0xc0000784e0 // ===========
p2 := &p // 等同于 var p2 *Person = &p fmt.Printf("p2:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p2, p2, &p2) p2.Name = "小明p2" fmt.Printf("p1:%+v 变量地址:%p\n", p, &p) fmt.Printf("p2:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p2, p2, &p2) fmt.Println("===========") // result: // p2:&{Name:小明 Age:0 Descprtion:} 指针变量指向地址(变量值):0xc000078480 变量地址:0xc000006030 // p1:{Name:小明p2 Age:0 Descprtion:} 变量地址:0xc000078480 // p2:&{Name:小明p2 Age:0 Descprtion:} 指针变量指向地址(变量值):0xc000078480 变量地址:0xc000006030 // ===========
p3.Age = 3 and
*p3 = Person{Name: "Xiao Ming p3" }, If the operation is performed after the second method, the modification of the structure in the first method will be overwritten.
p3 := new(Person) fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3) p3.Age = 3 // 等同于 (*p3).Age = 3 fmt.Println("================ 操作 Age ================") fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3) *p3 = Person{ Name: "小明p3", } fmt.Println("================ 操作 Name ================") fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3) p5 := p3 fmt.Println("================ p5 := p3 ================") fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3) fmt.Printf("p5:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p5, p5, &p5) p3.Name = "小明p3修改" fmt.Println("================ p3 修改 ================") fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3) fmt.Printf("p5:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p5, p5, &p5) fmt.Println("===========") // result: // p3:&{Name: Age:0 Descprtion:} 指针变量指向地址(变量值):0xc000078630 变量地址:0xc000006038 // ================ 操作 Age ================ // p3:&{Name: Age:3 Descprtion:} 指针变量指向地址(变量值):0xc000078630 变量地址:0xc000006038 // ================ 操作 Name ================ // p3:&{Name:小明p3 Age:0 Descprtion:} 指针变量指向地址(变量值):0xc000078630 变量地址:0xc000006038 // ================ p5 := p3 ================ // p5:&{Name:小明p3 Age:0 Descprtion:} 指针变量指向地址(变量值):0xc000078630 变量地址:0xc000006040 // ================ p3 修改 ================ // p3:&{Name:小明p3修改 Age:0 Descprtion:} 指针变量指向地址(变量值):0xc000078630 变量地址:0xc000006038 // p5:&{Name:小明p3修改 Age:0 Descprtion:} 指针变量指向地址(变量值):0xc000078630 变量地址:0xc000006040 // ===========
p4 := &Person{ Name: "小明p4",}fmt.Printf("%+v %p\n", p4, &p4)// result:// &{Name:小明p4 Age:0 Descprtion:} 0xc000006048
package mainimport "fmt"type Person struct { Name string Age int Descprtion string}func main() { p := Person{} p.Name = "小明" fmt.Printf("p:%+v 变量地址:%p\n", p, &p) fmt.Println("===========") p1 := p fmt.Printf("p1:%+v 变量地址:%p\n", p1, &p1) // 不存在写时复制 p1.Name = "小明p1" fmt.Printf("p:%+v 变量地址:%p\n", p, &p) fmt.Printf("p1:%+v 变量地址:%p\n", p1, &p1) fmt.Println("===========") p2 := &p fmt.Printf("p2:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p2, p2, &p2) p2.Name = "小明p2" fmt.Printf("p1:%+v 变量地址:%p\n", p, &p) fmt.Printf("p2:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p2, p2, &p2) fmt.Println("===========") p3 := new(Person) fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3) p3.Age = 3 // 等同于 (*p3).Age = 3 fmt.Println("================ 操作 Age ================") fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3) *p3 = Person{ Name: "小明p3", } fmt.Println("================ 操作 Name ================") fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3) p5 := p3 fmt.Println("================ p5 := p3 ================") fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3) fmt.Printf("p5:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p5, p5, &p5) p3.Name = "小明p3修改" fmt.Println("================ p3 修改 ================") fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3) fmt.Printf("p5:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p5, p5, &p5) fmt.Println("===========") p4 := &Person{ Name: "小明p4", } fmt.Printf("%+v %p\n", p4, &p4)}
The above is the detailed content of Explain Go struct instantiation and assignment with examples. For more information, please follow other related articles on the PHP Chinese website!