這篇文章主要介紹“Go struct實(shí)例化和賦值實(shí)例分析”,在日常操作中,相信很多人在Go struct實(shí)例化和賦值實(shí)例分析問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Go struct實(shí)例化和賦值實(shí)例分析”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!
Golang 中 struct 各種實(shí)例化和賦值方式,一會(huì)兒是值傳遞,一會(huì)兒又是指針,讓人一頭霧水,于是我決定梳理一下,整個(gè)明白。
先定義一個(gè)結(jié)構(gòu)體,下面結(jié)合代碼進(jìn)行講解。
package mainimport "fmt"type Person struct { Name string Age int Descprtion string}
p 以最常規(guī)的方式實(shí)例化一個(gè) struct,變量 p 得到一個(gè) Person 結(jié)構(gòu)體。
p := Person{} p.Name = "小明" fmt.Printf("p:%+v 變量地址:%p\n", p, &p) fmt.Println("===========") // result: // p:{Name:小明 Age:0 Descprtion:} 變量地址:0xc000078480 // ===========
變量 p1 由 p 賦值而來,由于 Golang 語言是值傳遞
,賦值后,對(duì) p1 的修改并不會(huì)影響到 p;
從第一個(gè)輸出也可以看得出,Golang 的賦值并不存在像PHP變量賦值時(shí)的寫時(shí)復(fù)制
(copy on write)機(jī)制。
p1 := p fmt.Printf("p1:%+v 變量地址:%p\n", p1, &p1) // 不存在寫時(shí)復(fù)制 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 是一個(gè)指針,存放著指向 p 的地址。當(dāng) p2 修改了結(jié)構(gòu)體中元素 Name 時(shí),通過 p 訪問結(jié)構(gòu)體對(duì)應(yīng)的值也相應(yīng)地發(fā)生了變化。
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 將開辟一塊內(nèi)存,返回內(nèi)存地址給 p3,也即 p3 是一個(gè)指向這塊內(nèi)存的指針。
p3 是指向結(jié)構(gòu)體的指針,它有兩種方式可以操作結(jié)構(gòu)體,p3.Age = 3
和 *p3 = Person{Name: "小明p3"}
, 如果第二種方式后操作,將會(huì)覆蓋第一種方式對(duì)結(jié)構(gòu)體的修改。
由于 p3 是指針,當(dāng) p3 賦值給 p5 時(shí),p5 也將指向這塊內(nèi)存地址。
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 的實(shí)例化方式也將得到一個(gè)指針,這種實(shí)例化方式與 p3 的實(shí)例化是相同的,但 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) // 不存在寫時(shí)復(fù)制 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)}
到此,關(guān)于“Go struct實(shí)例化和賦值實(shí)例分析”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。