먼저 구조를 정의하고 아래에서 코드와 함께 설명해보세요.
package mainimport "fmt"type Person struct { Name string Age int Descprtion string}
예제 1
p := Person{} p.Name = "小明" fmt.Printf("p:%+v 变量地址:%p\n", p, &p) fmt.Println("===========") // result: // p:{Name:小明 Age:0 Descprtion:} 变量地址:0xc000078480 // ===========
예제 2
값 전송
이므로 할당 후 p1의 수정은 p에 영향을 미치지 않습니다. Golang의 할당에는 PHP 변수 할당과 같은 쓰기 시 복사
(쓰기 시 복사) 메커니즘이 없다는 것도 출력에서 볼 수 있습니다.
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 // ===========
예 3值传递
,赋值后,对 p1 的修改并不会影响到 p;
从第一个输出也可以看得出,Golang 的赋值并不存在像PHP变量赋值时的写时复制
(copy on write)机制。
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 // ===========
利用取地址符将 p 的地址赋值给 p2,变量 p2 是一个指针,存放着指向 p 的地址。当 p2 修改了结构体中元素 Name 时,通过 p 访问结构体对应的值也相应地发生了变化。
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 // ===========
变量 p3 由 new(Person) 得来。new 将开辟一块内存,返回内存地址给 p3,也即 p3 是一个指向这块内存的指针。
p3 是指向结构体的指针,它有两种方式可以操作结构体,p3.Age = 3
和 *p3 = Person{Name: "小明p3"}
p4 := &Person{ Name: "小明p4",}fmt.Printf("%+v %p\n", p4, &p4)// result:// &{Name:小明p4 Age:0 Descprtion:} 0xc000006048예 4
p3은 구조에 대한 포인터입니다. 구조를 작동하는 방법에는 p3.Age = 3
및 *p3 = Person{Name: "Xiao Ming p3"}이 있습니다. code>에서 두 번째 방법 이후에 연산을 수행하면 첫 번째 방법에서 수정된 구조를 덮어쓰게 됩니다.
p3은 포인터이므로 p3이 p5에 할당되면 p5도 이 메모리 주소를 가리킵니다.
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)}
예제 5
🎜 p4의 인스턴스화 방법도 포인터를 얻습니다. 이 인스턴스화 방법은 p3의 인스턴스화와 동일하지만 p4의 쓰기 방법이 더 일반적으로 사용됩니다. 🎜🎜🎜🎜rrreee🎜첨부된 코드는 전체 코드입니다: 🎜rrreee🎜End! 🎜위 내용은 예시를 통해 Go 구조체 인스턴스화 및 할당 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!