Go語(yǔ)言append()方法的運(yùn)行機(jī)制:為什么append(x, 4)和append(x, 5)的結(jié)果并非預(yù)期?

Go語(yǔ)言append()方法的運(yùn)行機(jī)制:為什么append(x, 4)和append(x, 5)的結(jié)果并非預(yù)期?

go語(yǔ)言append()函數(shù)的運(yùn)行機(jī)制詳解:意料之外的結(jié)果

本文深入探討Go語(yǔ)言append()函數(shù)的底層機(jī)制,并通過(guò)一個(gè)示例代碼解釋其非直觀行為。該示例揭示了append()并非簡(jiǎn)單的值復(fù)制,而是與底層數(shù)組的內(nèi)存分配和共享息息相關(guān)。

示例代碼如下:

package main  import "fmt"  func main() {     x := make([]int, 0, 10)     x = append(x, 1, 2, 3)     y := append(x, 4)     z := append(x, 5)     fmt.Println(x)     fmt.Println(y)     fmt.Println(z) }

運(yùn)行結(jié)果顯示y和z的輸出與預(yù)期不符:y輸出[1 2 3 4],z輸出[1 2 3 5]。這與許多開發(fā)者對(duì)append()的理解存在偏差。其根本原因在于對(duì)Go語(yǔ)言切片(slice)的底層實(shí)現(xiàn)和append()函數(shù)的運(yùn)作機(jī)制缺乏深入了解。

立即學(xué)習(xí)go語(yǔ)言免費(fèi)學(xué)習(xí)筆記(深入)”;

Go語(yǔ)言切片并非直接指向底層數(shù)組,而是一個(gè)包含指針、長(zhǎng)度和容量的結(jié)構(gòu)體。append()函數(shù)在容量允許的情況下,直接在底層數(shù)組上追加元素,無(wú)需數(shù)據(jù)復(fù)制。只有當(dāng)切片容量不足時(shí),才會(huì)重新分配內(nèi)存,并將原有數(shù)據(jù)復(fù)制到新數(shù)組。

代碼分析:

  1. x = append(x, 1, 2, 3):將元素1、2、3追加到切片x。由于x的容量為10,足夠容納這三個(gè)元素,append()直接在x的底層數(shù)組中追加,x的長(zhǎng)度變?yōu)?。
  2. y = append(x, 4):將元素4追加到x,生成新的切片y。由于容量充足,append()仍在同一底層數(shù)組操作,將4追加到數(shù)組末尾,y長(zhǎng)度變?yōu)?,y與x共享同一底層數(shù)組。
  3. z = append(x, 5):將元素5追加到x,生成新的切片z。同樣,由于容量足夠,append()在同一底層數(shù)組中追加元素5,z長(zhǎng)度變?yōu)?,z與x和y共享同一底層數(shù)組。但x的長(zhǎng)度仍為3,因此打印x只顯示前三個(gè)元素。y和z長(zhǎng)度為4,顯示追加的元素4和5,導(dǎo)致z覆蓋了y的最后一個(gè)元素。

關(guān)鍵在于x、y、z三個(gè)切片共享同一底層數(shù)組。append操作直接修改底層數(shù)組,后續(xù)append操作會(huì)影響所有共享該數(shù)組的切片。理解切片的共享特性才能準(zhǔn)確解釋代碼結(jié)果。

以上就是Go語(yǔ)言append()方法的運(yùn)行機(jī)制:

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊11 分享