结合Go struct化和赋值
先定义一个结构体,下面结合代码进行讲解。
package mainimport "fmt"type Person struct {
Name string
Age int
Descprtion string}
实例一
p 以最常规的方式实例化一个 struct,变量 p 得到一个 Person 结构体。
p := Person{}
p.Name = "小明"
fmt.Printf("p:% v 变量地址:%p\n", p, &p)
fmt.Println("===========")
// result:
// p:{Name:小明 Age:0 Descprtion:} 变量地址:0xc000078480
// ===========
实例二
变量 p1 由 p 赋值而来,由于 Golang 语言是值传递
,赋值后,对 p1 的修改并不会影响到 p;
从第一个输出也可以看得出,Golang 的赋值并不存在像PHP变量赋值时的写时复制
(copy on write)机制。
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
// ===========
实例三
利用取地址符将 p 的地址赋值给 p2,变量 p2 是一个指针,存放着指向 p 的地址。当 p2 修改了结构体中元素 Name 时,通过 p 访问结构体对应的值也相应地发生了变化。
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 由 new(Person) 得来。new 将开辟一块内存,返回内存地址给 p3,也即 p3 是一个指向这块内存的指针。
p3 是指向结构体的指针,它有两种方式可以操作结构体,p3.Age = 3
和 *p3 = Person{Name: "小明p3"}
, 如果第二种方式后操作,将会覆盖第一种方式对结构体的修改。
由于 p3 是指针,当 p3 赋值给 p5 时,p5 也将指向这块内存地址。
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 的实例化方式也将得到一个指针,这种实例化方式与 p3 的实例化是相同的,但 p4 的写法更常使用。
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)}
End!
本文出至:学新通
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通
- 本文地址: https://www.swvq.com/boutique/detail/15865
- 联系方式: luke.wu@swvq.com
- 来源链接: www.php.cn/be/go/484539.html
系列文章
更多
同类精品
更多
精彩评论
-
windows上查看nginx是否启动
PHP中文网 04-19 -
2023年最新的28道PHP面试题附答案
PHP中文网 03-27 -
docker hub 进不去怎么办
PHP中文网 03-15 -
推荐五款xml编辑工具
PHP中文网 03-04 -
navicat怎样清除注册表
PHP中文网 04-05 -
ChatGPT应用通过Axios+EventSource使用GPT3.5 API
uWydnA 03-13 -
强力推荐10款好看使用的Bootstrap后台管理系统模板
PHP中文网 03-09 -
vscode怎么调整代码大小两种方法
PHP中文网 03-11 -
navicat删除的数据能还原吗
PHP中文网 04-09 -
navicat连接sqlserver数据库
PHP中文网 04-03