Golang中切片長度和容量的區(qū)別示例詳解
首先要知道在Golang中,切片的底層實際就是數(shù)組。
1.切片的長度:
切片的長度指切片中元素的數(shù)量,可以使用len()函數(shù)查詢其切片的長度。
示例1:
package main import "fmt" func main(){ slice := []int{1,3,2,6,4} # 調(diào)用len查看長度 length := len(slice) fmt.Printf("slice01的長度是:%v", length) } // 輸出結(jié)果 // slice的長度是:5
在上面代碼中,變量length就是切片的長度(結(jié)果是5)
2.切片的容量:
切片的容量是指切片底層數(shù)組的長度,可以使用cap()函數(shù)查看容量
示例2:
package main import "fmt" func main(){ slice := []int{1,3,2,6,4} // 調(diào)用cap查看容量 capacity := cap(slice) fmt.Printf("slice01的容量是:%v", capacity) } // 輸出結(jié)果 // slice的容量是:5
在上面代碼中,變量capacity就是切片的容量(結(jié)果也是5)
3.通過上面兩個示例看不出區(qū)別,我們看下面的示例:
示例3
package main import "fmt" func main(){ // 通過make函數(shù)來創(chuàng)建slice, 4表示切片的長度, 10標識切片的容量 slice := make([]int, 4, 6) length := len(slice) capacity := cap(slice) fmt.Printf("slice01的長度是:%v\n", length) fmt.Printf("slice01的容量是:%v\n", capacity) } // 輸出結(jié)果 // slice01的長度是:4 // slice01的容量是:6
你可以想象成:當執(zhí)行slice := make([]int, 4, 10)
的時候,程序在底層創(chuàng)建了一個長度為6的數(shù)組,切片slice引用了前面4個元素,就生成了slice這個切片,當前切片值是:{0, 0, 0, 0},剩下的2個元素則暫時沒有引用。
4.通過對切片的增加,查看切片與底層數(shù)組的變化
我們知道,golang中切片和數(shù)組的主要區(qū)別在于數(shù)組是定長的,切片是變長的。但我們在示例3中定義了切片的容量是6,那如果超過6個元素了,將會發(fā)生什么呢?
示例4
package main import "fmt" func main(){ // 通過make函數(shù)來創(chuàng)建slice, 4表示切片的長度, 10標識切片的容量 slice := make([]int, 4, 6) length := len(slice) capacity := cap(slice) fmt.Printf("slice01的長度是:%v\n", length) fmt.Printf("slice01的容量是:%v\n", capacity) //第一次向切片slice內(nèi)添加元素 slice = append(slice, 1) //打印slice的長度,容量,內(nèi)存地址(slice[0]的內(nèi)存地址) fmt.Printf("\n\n第一次結(jié)果:") fmt.Printf("slice的長度是:%v\n", len(slice)) fmt.Printf("slice的容量是:%v\n", cap(slice)) fmt.Printf("slice的內(nèi)存地址是:%v\n", &slice[0]) // 第二次向slice內(nèi)添加元素 slice = append(slice, 1) //打印slice的長度,容量,內(nèi)存地址(slice[0]的內(nèi)存地址) fmt.Printf("\n\n第二次結(jié)果:") fmt.Printf("slice的長度是:%v\n", len(slice)) fmt.Printf("slice的容量是:%v\n", cap(slice)) fmt.Printf("slice的內(nèi)存地址是:%v\n", &slice[0]) // 第三次向slice內(nèi)添加元素 slice = append(slice, 1) //打印slice的長度,容量,內(nèi)存地址(slice[0]的內(nèi)存地址) fmt.Printf("\n\n第三次結(jié)果:") fmt.Printf("slice的長度是:%v\n", len(slice)) fmt.Printf("slice的容量是:%v\n", cap(slice)) fmt.Printf("slice的內(nèi)存地址是:%v\n", &slice[0]) } // slice01的長度是:4 // slice01的容量是:6 // 第一次結(jié)果:slice的長度是:5 // slice的容量是:6 // slice的內(nèi)存地址是:0xc00000e390 // 第二次結(jié)果:slice的長度是:6 // slice的容量是:6 // slice的內(nèi)存地址是:0xc00000e390 // 第三次結(jié)果:slice的長度是:7 // slice的容量是:12 // slice的內(nèi)存地址是:0xc000060060
通過示例4我們可以發(fā)現(xiàn):我們初始化切片長度為4, 容量為6的時候。
當?shù)谝淮魏偷诙蜗蚯衅瑑?nèi)添加元素后,只有切片的長度增加,容量和內(nèi)存地址都沒改變
當?shù)谌蜗蚯衅瑑?nèi)添加元素后,長度增加了1,容量變成了之前的2倍,內(nèi)存地址也發(fā)生了改變。
由此我們可以推斷出:
**總結(jié):**當切片的元素長度超過了默認的容量之后,程序會重新創(chuàng)建一個底層數(shù)組和切片綁定,且新的數(shù)組的長度為原來的兩倍(切片的容量變成原來的兩倍)
5. 注意用法:
示例5
package main import "fmt" func main() { slice := make([]int, 4, 4) slice2 := make([]int, 4, 5) // 調(diào)用下方定義的test函數(shù) test(slice) test(slice2) // 輸出兩個切片調(diào)用test函數(shù)后的結(jié)果 fmt.Printf("slice的結(jié)果: %v\n", slice) fmt.Printf("slice2的結(jié)果: %v\n", slice2) } func test(s []int) { s = append(s, 1) for i := 0; i < len(s); i++ { s[i] = 100 } } // slice的結(jié)果: [0 0 0 0] // slice2的結(jié)果: [100 100 100 100]
切片容量不同,導(dǎo)致了最終結(jié)果不同。
總結(jié)
到此這篇關(guān)于Golang中切片長度和容量區(qū)別的文章就介紹到這了,更多相關(guān)Golang切片長度和容量內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
gin自定義中間件解決requestBody不可重復(fù)讀問題(最新推薦)
這篇文章主要介紹了gin自定義中間件解決requestBody不可重復(fù)讀問題,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04Golang?urfave/cli庫簡單應(yīng)用示例詳解
這篇文章主要為大家介紹了Golang?urfave/cli庫簡單應(yīng)用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-09-09利用systemd部署golang項目的實現(xiàn)方法
這篇文章主要介紹了利用systemd部署golang項目的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧2019-11-11