Go 面試題 003:深拷貝和淺拷貝的區(qū)別?
大家好,我是明哥。
歡迎大家再次來(lái)到 『Go 語(yǔ)言面試題庫(kù)』 這個(gè)專欄
本專欄內(nèi)容,已經(jīng)上傳 github:https://github.com/iswbm/golang-interview
請(qǐng)大家?guī)蛶兔θc(diǎn)個(gè)小 ??,在那里我對(duì)題庫(kù)進(jìn)行了分類整理。
第六題

請(qǐng)聽(tīng)題:
深拷貝和淺拷貝的區(qū)別是什么?
# 1. 什么是拷貝?
當(dāng)你把 a 變量賦值給 b 變量時(shí),其實(shí)就是把 a 變量拷貝給 b 變量
a := "hello"
b := a
這只是拷貝最簡(jiǎn)單的一種形式,而有些形式卻表現(xiàn)得非常的隱蔽。比如:
你往一個(gè)函數(shù)中傳參
你向通道中傳入對(duì)象
這些其實(shí)在 Go編譯器中都會(huì)進(jìn)行拷貝的動(dòng)作。
# 2. 什么是深淺拷貝?
知道了什么是拷貝,那我們?cè)偻铧c(diǎn)開(kāi)挖,聊聊深淺拷貝。
不過(guò)先別急,咱先了解下數(shù)據(jù)結(jié)構(gòu)的兩種類型:
值類型 :String,Array,Int,Struct,F(xiàn)loat,Bool
引用類型:Slice,Map
這兩種不同的類型在拷貝的時(shí)候,在拷貝的時(shí)候效果是完全不一樣的,這對(duì)于很多新手可能是一個(gè)坑。
對(duì)于值類型來(lái)說(shuō),你的每一次拷貝,Go 都會(huì)新申請(qǐng)一塊內(nèi)存空間,來(lái)存儲(chǔ)它的值,改變其中一個(gè)變量,并不會(huì)影響另一個(gè)變量。
func main() {
aArr := [3]int{0,1,2}
fmt.Printf("打印 aArr: %v \n", aArr)
bArr := aArr
aArr[0] = 88
fmt.Println("將 aArr 拷貝給 bArr 后,并修改 aArr[0] = 88")
fmt.Printf("打印 aArr: %v \n", aArr)
fmt.Printf("打印 bArr: %v \n", bArr)
}
從輸出結(jié)果來(lái)看,aArr 和 bArr 相互獨(dú)立,互不干擾
打印 aArr: [0 1 2]
將 aArr 拷貝給 bArr 后,并修改 aArr[0] = 88
打印 aArr: [88 1 2]
打印 bArr: [0 1 2]
對(duì)于引用類型來(lái)說(shuō),你的每一次拷貝,Go 不會(huì)申請(qǐng)新的內(nèi)存空間,而是使用它的指針,兩個(gè)變量名其實(shí)都指向同一塊內(nèi)存空間,改變其中一個(gè)變量,會(huì)直接影響另一個(gè)變量。
func main() {
aslice := []int{0,1,2}
fmt.Printf("打印 aslice: %v \n", aslice)
bslice := aslice
aslice[0] = 88
fmt.Println("將 aslice 拷貝給 bslice 后,并修改 aslice[0] = 88")
fmt.Printf("打印 aslice: %v \n", aslice)
fmt.Printf("打印 bslice: %v \n", bslice)
}
從輸出結(jié)果來(lái)看,aslice 的更新直接反映到了 bslice 的值。
打印 aslice: [0 1 2]
將 aslice 拷貝給 bslice 后,并修改 aslice[0] = 88
打印 aslice: [88 1 2]
打印 bslice: [88 1 2]
是不是很簡(jiǎn)單?跟著明哥一起來(lái)攻克 Go 的各個(gè)邊邊角角的知識(shí)吧
加油噢,我們下篇見(jiàn)

???
