go值賦值和引用賦值的使用
值賦值(Value Assignment)
值賦值是指將一個(gè)變量的值復(fù)制給另一個(gè)變量。當(dāng)進(jìn)行值賦值時(shí),會(huì)創(chuàng)建原始值的一個(gè)副本,并將副本賦值給目標(biāo)變量。這意味著目標(biāo)變量和源變量是完全獨(dú)立的,它們引用的是不同的內(nèi)存地址。修改目標(biāo)變量的值不會(huì)影響源變量的值。
var a = 10 var b = a // 值賦值 b = 20 fmt.Println(a) // 輸出: 10 fmt.Println(b) // 輸出: 20
在上述代碼中,將變量 a
的值賦值給變量 b
,然后修改 b
的值不會(huì)影響到 a
。
引用賦值(Reference Assignment)
引用賦值是指將一個(gè)引用(指針、切片、映射、通道等)復(fù)制給另一個(gè)變量。當(dāng)進(jìn)行引用賦值時(shí),目標(biāo)變量和源變量引用的是相同的底層數(shù)據(jù)。它們指向同一塊內(nèi)存地址。因此,修改目標(biāo)變量會(huì)影響源變量,因?yàn)樗鼈児蚕硐嗤臄?shù)據(jù)。
var slice1 = []int{1, 2, 3} var slice2 = slice1 // 引用賦值 slice2[1] = 10 fmt.Println(slice1) // 輸出: [1 10 3] fmt.Println(slice2) // 輸出: [1 10 3]
在上述代碼中,將切片 slice1
的引用賦值給 slice2
,然后修改 slice2
中的元素會(huì)影響到 slice1
,因?yàn)樗鼈円玫氖峭粔K內(nèi)存。
需要注意的是,值賦值和引用賦值的行為取決于變量的類型。對于基本類型(如整數(shù)、浮點(diǎn)數(shù)、布爾值等),進(jìn)行值賦值時(shí)會(huì)復(fù)制值;對于引用類型(如切片、映射、通道等),進(jìn)行引用賦值時(shí)會(huì)共享底層數(shù)據(jù)。
結(jié)構(gòu)體的值賦值在 Go 語言中,結(jié)構(gòu)體類型的賦值操作是進(jìn)行值拷貝
package main import "fmt" type Person struct { Name string Age int } func main() { p1 := Person{Name: "Alice", Age: 30} p2 := p1 p3 := Person{Name: p1.Name, Age: p1.Age} p1.Age = 31 fmt.Println(p2) // 輸出: {Alice 30} fmt.Println(p3) // 輸出: {Alice 30} }
在執(zhí)行 p2 := p1 時(shí),會(huì)創(chuàng)建一個(gè)新的結(jié)構(gòu)體變量 p2,并將 p1 的字段值逐個(gè)復(fù)制到 p2 中。
創(chuàng)建了一個(gè)新的結(jié)構(gòu)體變量 p3,并將 p1 的字段值逐個(gè)復(fù)制給 p3。因此,p3 是一個(gè)獨(dú)立的結(jié)構(gòu)體變量,它和 p1 指向不同的內(nèi)存空間。當(dāng)對 p1 的字段進(jìn)行修改時(shí),p3 不會(huì)受到影響,因?yàn)樗鼈円玫氖遣煌膬?nèi)存地址。
結(jié)構(gòu)體的引用賦值結(jié)構(gòu)體的引用賦值是指將一個(gè)結(jié)構(gòu)體變量的引用(指針)賦值給另一個(gè)結(jié)構(gòu)體變量。通過引用賦值,兩個(gè)結(jié)構(gòu)體變量將引用相同的底層數(shù)據(jù)。
引用賦值適用于結(jié)構(gòu)體類型,包括自定義的結(jié)構(gòu)體類型和內(nèi)置的結(jié)構(gòu)體類型(如切片、映射等)。
type Person struct { Name string Age int } func main() { p1 := Person{Name: "Alice", Age: 30} // 引用賦值 p2 := &p1 p1.Age = 31 fmt.Println(p1) // 輸出: {Alice 31} fmt.Println(*p2) // 輸出: {Alice 31} }
在上述代碼中,通過 p2 := &p1 將 p1 的指針賦值給了 p2,實(shí)現(xiàn)了引用賦值。p2 和 p1 都指向相同的結(jié)構(gòu)體數(shù)據(jù)。
因此,當(dāng)修改 p1 的字段值時(shí),通過 p2 訪問也會(huì)反映出修改的結(jié)果。這是因?yàn)?p2 和 p1 引用了同一塊內(nèi)存空間,它們共享相同的數(shù)據(jù)。
需要注意的是,引用賦值是一種淺拷貝操作。這意味著只有結(jié)構(gòu)體本身被復(fù)制,而結(jié)構(gòu)體內(nèi)部的引用類型字段(如切片、映射等)不會(huì)被復(fù)制。修改引用類型字段時(shí),會(huì)影響到所有引用該字段的結(jié)構(gòu)體變量。
type Person struct { Name string Friends []string } func main() { p1 := Person{Name: "Alice", Friends: []string{"Bob", "Charlie"}} // 引用賦值 p2 := &p1 p1.Friends[0] = "David" fmt.Println(p1) // 輸出: {Alice [David Charlie]} fmt.Println(*p2) // 輸出: {Alice [David Charlie]} }
在上述代碼中,通過引用賦值將 p1 的指針賦值給了 p2。修改 p1 的 Friends 字段的元素時(shí),通過 p2 訪問也會(huì)反映出修改的結(jié)果。這是因?yàn)?p1 和 p2 共享同一個(gè)切片的引用,它們指向相同的底層數(shù)據(jù)。
切片的值賦值copy 是一個(gè)內(nèi)置函數(shù),用于將一個(gè)切片的元素復(fù)制到另一個(gè)切片中
package main import "fmt" func main() { ls := []int{2, 45, 4, 57} var lk = make([]int, 5) copy(lk, ls) lk[1] = 2222 fmt.Println(ls, lk) }
通過 copy 函數(shù)將 ls 的元素復(fù)制到 lk,并修改了 lk[1] 的值,這個(gè)修改只會(huì)影響到 lk 自身,不會(huì)影響 ls。因?yàn)?copy 函數(shù)會(huì)將源切片的元素值復(fù)制到目標(biāo)切片中。在這個(gè)過程中,源切片和目標(biāo)切片是完全獨(dú)立的,它們分別引用不同的底層數(shù)組。修改目標(biāo)切片 lk 中的元素值不會(huì)影響原始切片 ls,因?yàn)樗鼈円玫氖遣煌膬?nèi)存空間。
到此這篇關(guān)于go值賦值和引用賦值的使用的文章就介紹到這了,更多相關(guān)go值賦值和引用賦值內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語言高效I/O并發(fā)處理雙緩沖和Exchanger模式實(shí)例探索
這篇文章主要介紹了Go語言高效I/O并發(fā)處理雙緩沖和Exchanger模式實(shí)例探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01Go語言使用Buffer實(shí)現(xiàn)高性能處理字節(jié)和字符
在?Go?中,bytes.Buffer?是一個(gè)非常高效的類型,用于處理字節(jié)數(shù)據(jù)的讀寫操作,本文將詳細(xì)介紹一下如何使用Buffer實(shí)現(xiàn)高性能處理字節(jié)和字符,有需要的小伙伴可以了解下2025-01-01jenkins配置golang?代碼工程自動(dòng)發(fā)布的實(shí)現(xiàn)方法
這篇文章主要介紹了jenkins配置golang?代碼工程自動(dòng)發(fā)布,jks是個(gè)很好的工具,使用方法也很多,我只用了它簡單的功能,對jenkins配置golang相關(guān)知識(shí)感興趣的朋友一起看看吧2022-07-07Go語言實(shí)現(xiàn)Snowflake雪花算法
雪花算法產(chǎn)生的背景當(dāng)然是twitter高并發(fā)環(huán)境下對唯一ID生成的需求,得益于twitter內(nèi)部牛的技術(shù),雪花算法能夠流傳于至今并且被廣泛使用,本文就詳細(xì)的介紹一下,感興趣的可以了解一下2021-06-06