欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

golang中的切片

索引:https://waterflow.link/articles/

目前創(chuàng)新互聯(lián)公司已為上千多家的企業(yè)提供了網(wǎng)站建設、域名、虛擬空間、網(wǎng)站托管、服務器托管、企業(yè)網(wǎng)站設計、桃源網(wǎng)站維護等服務,公司將堅持客戶導向、應用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

在go中切片的底層是數(shù)組,所以切片的數(shù)據(jù)連續(xù)存儲在數(shù)組的數(shù)據(jù)結構中。如果底層的數(shù)組滿了,切片還需要添加元素的話,底層數(shù)組就需要擴容。如果底層數(shù)組幾乎為空時,就會縮容。

在切片內(nèi)部其包含一個指向底部數(shù)組的指針、切片的長度、切片的容量。長度是指切片包含的元素樹,容量底層數(shù)組中的元素數(shù)。

我們先看個例子:

s := make([]int, 2, 4)

我們初始化一個長度為2,容量為4的切片。長度是必選的,容量可選。當不指定容量時,容量和長度相同,也就是底層數(shù)組的長度。

因為長度為2,所以go只初始化了2個元素。我們可以打印下看下結果:

package main

import "fmt"

func main() {
	s := make([]int, 2, 4)
	fmt.Printf("s:%v,len(s):%d,cap(s):%d\n",
		s, len(s), cap(s))
}
go run 4.go
s:[0 0],len(s):2,cap(s):4

下面我們把s[1]設置為1,所以s的第二個元素會被更新為1,s的長度和容量不會變化

我們看下執(zhí)行結果:

package main

import "fmt"

func main() {
	s := make([]int, 2, 4)
	s[1] = 1
	fmt.Printf("s:%v,len(s):%d,cap(s):%d\n",
		s, len(s), cap(s))
}
go run 4.go
s:[0 1],len(s):2,cap(s):4

但是當我們設置s[2] = 1時會報錯,像下面這樣:

go run 4.go
panic: runtime error: index out of range [2] with length 2

但是我們的容量是4,也就是底層數(shù)組還有2個空閑元素。那我們該如何給剩下的元素賦值呢?

我們可以使用go的內(nèi)置函數(shù)append,他可以將元素追加到切片的末尾。它可以追加一個元素到切片末尾:

s = append(s, 1)

也可以追加多個元素到切片末尾:

s = append(s, 1, 2)
s = append(s, []int{1, 2}...)

還有一種比較特殊的情況,將字符串追加到字節(jié)切片末尾:

s = append([]byte("hello"), "world"...)

現(xiàn)在我們執(zhí)行append(s, 2),將元素2追加到s[1]后面,我們會得到下面的結果

切片的長度變成了3,容量還是4:

package main

import "fmt"

func main() {
	s := make([]int, 2, 4)
	s[1] = 1
	s = append(s, 2)
	fmt.Printf("s:%v,len(s):%d,cap(s):%d\n",
		s, len(s), cap(s))
}
go run 4.go
s:[0 1 2],len(s):3,cap(s):4

現(xiàn)在我們?nèi)绻苯犹砑?個元素進去,像下面這樣:

s = append(s, 1, 2, 3)

我們會得到下面的結果:

package main

import "fmt"

func main() {
	s := make([]int, 2, 4)
	s[1] = 1
	s = append(s, 2)
	s = append(s, 1, 2, 3)
	fmt.Printf("s:%v,len(s):%d,cap(s):%d\n",
		s, len(s), cap(s))
}
go run 4.go
s:[0 1 2 1 2 3],len(s):6,cap(s):8

我們發(fā)現(xiàn)現(xiàn)在元素的長度變成了6個,這個很好理解,因為我們總共添加了6個元素。但是切片的容量為什么會是8呢?

這是因為當我們添加第5個元素時,發(fā)現(xiàn)已經(jīng)超過切片的容量了。這個時候會觸發(fā)擴容,會將容量加倍,然后復制所有元素創(chuàng)建另一個數(shù)組。然后會把剩下的2和3插進去。

擴容機制:如果不到1024個元素,會成倍擴容;超過1024個元素,按25%擴容

切片中還提供了一種半開區(qū)間的賦值方式,保留第一個索引,排除第二個索引,像下面這樣:

package main

import "fmt"

func main() {
	s := make([]int, 2, 4)
	s[1] = 1
	s = append(s, 2)
	s = append(s, 1, 2, 3)
	fmt.Printf("s:%v,len(s):%d,cap(s):%d\n",
		s, len(s), cap(s))
	s2 := s[1:2] // 這里重新賦值給s2
	fmt.Printf("s2:%v,len(s2):%d,cap(s2):%d\n",
		s2, len(s2), cap(s2))
}
go run 4.go
s:[0 1 2 1 2 3],len(s):6,cap(s):8
s2:[1],len(s2):1,cap(s2):7

切片s和s2此時是引用同一個底層數(shù)組的,但是由于s2是從1開始,所以容量變成了7

這時如果我們修改了s2[0]或者s[1],實際上他們指向的是底層數(shù)組的同一個元素。所以s2[0]或者s[1]都會被修改掉。

package main

import "fmt"

func main() {
	s := make([]int, 2, 4)
	s[1] = 1
	s = append(s, 2)
	s = append(s, 1, 2, 3)
	s2 := s[1:2]
	s2[0] = 8 // 這里
	fmt.Printf("修改倆切片指向的同一個元素:s:%v,len(s):%d,cap(s):%d)----s2:%v,len(s2):%d,cap(s2):%d\n",
		s, len(s), cap(s), s2, len(s2), cap(s2))
}
go run 4.go
修改倆切片指向的同一個元素:s:[0 8 2 1 2 3],len(s):6,cap(s):8)----s2:[8],len(s2):1,cap(s2):7

接著我們繼續(xù)往s2中插入一個元素,看看會發(fā)生什么:

package main

import "fmt"

func main() {
	s := make([]int, 2, 4)
	s[1] = 1
	s = append(s, 2)
	s = append(s, 1, 2, 3)
	s2 := s[1:2]
	s2[0] = 8
	// 插入元素6
	s2 = append(s2, 6)
	fmt.Printf("往s2插入一個元素:s:%v,len(s):%d,cap(s):%d----s2:%v,len(s2):%d,cap(s2):%d\n",
		s, len(s), cap(s), s2, len(s2), cap(s2))
}
go run 4.go
往s2插入一個元素:s:[0 8 6 1 2 3],len(s):6,cap(s):8----s2:[8 6],len(s2):2,cap(s2):7

我們可以看到s2[1]的元素寫進去了,長度變?yōu)?。但是s2的長度并沒有變化,s2[2]的元素卻被修改為了6。這是因為往s2插入元素時并沒有超過s2的容量,所以還是共用同一個底層數(shù)組。

那現(xiàn)在我們繼續(xù)往s2中添加6個元素,看看超出容量后的底層數(shù)組會是什么樣的:

package main

import "fmt"

func main() {
	s := make([]int, 2, 4)
	s[1] = 1
	s = append(s, 2)
	s = append(s, 1, 2, 3)
	s2 := s[1:2]
	s2[0] = 8
	s2 = append(s2, 6)
	// 繼續(xù)插入6個元素
	s2 = append(s2, 7)
	s2 = append(s2, 8)
	s2 = append(s2, 9)
	s2 = append(s2, 10)
	s2 = append(s2, 11)
	s2 = append(s2, 12)
	fmt.Printf("繼續(xù)往s2插入6個元素:s:%v,len(s):%d,cap(s):%d----s2:%v,len(s2):%d,cap(s2):%d\n",
		s, len(s), cap(s), s2, len(s2), cap(s2))
}
go run 4.go
繼續(xù)往s2插入6個元素:s:[0 8 6 7 8 9],len(s):6,cap(s):8----s2:[8 6 7 8 9 10 11 12],len(s2):8,cap(s2):14

我們來分析下上面的例子:

  1. 當我們往s2插入7的時候,此時s2的長度變?yōu)?,容量還是7。s[3]對應也被修改。
  2. 當我們往s2插入8的時候,此時s2的長度變?yōu)?,容量還是7。s[4]對應也被修改。
  3. 當我們往s2插入9的時候,此時s2的長度變?yōu)?,容量還是7。s[5]對應也被修改。
  4. 當我們往s2插入10的時候,此時s2的長度變?yōu)?,容量還是7。s[6]對應也被修改。
  5. 當我們往s2插入11的時候,此時s2的長度變?yōu)?,容量還是7。因為s切片長度為6,所以沒有變化。
  6. 當我們往s2插入12的時候,此時s2超過s2的容量引發(fā)擴容,底層數(shù)組被復制,s2指向一個新的容量為14的數(shù)組。因為s長度小于容量,所以還是指向原來的數(shù)組。

我們可以通過下面的圖片,增加更清晰的認識。

分享名稱:golang中的切片
本文地址:http://chinadenli.net/article38/dsoidpp.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供、網(wǎng)站策劃手機網(wǎng)站建設、小程序開發(fā)網(wǎng)站制作、外貿(mào)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設