Golang中切片長度和容量的區(qū)別示例詳解
首先要知道在Golang中,切片的底層實(shí)際就是數(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.通過上面兩個(gè)示例看不出區(qū)別,我們看下面的示例:
示例3
package main
import "fmt"
func main(){
// 通過make函數(shù)來創(chuàng)建slice, 4表示切片的長度, 10標(biāo)識切片的容量
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
你可以想象成:當(dāng)執(zhí)行slice := make([]int, 4, 10)的時(shí)候,程序在底層創(chuàng)建了一個(gè)長度為6的數(shù)組,切片slice引用了前面4個(gè)元素,就生成了slice這個(gè)切片,當(dāng)前切片值是:{0, 0, 0, 0},剩下的2個(gè)元素則暫時(shí)沒有引用。
4.通過對切片的增加,查看切片與底層數(shù)組的變化
我們知道,golang中切片和數(shù)組的主要區(qū)別在于數(shù)組是定長的,切片是變長的。但我們在示例3中定義了切片的容量是6,那如果超過6個(gè)元素了,將會發(fā)生什么呢?
示例4
package main
import "fmt"
func main(){
// 通過make函數(shù)來創(chuàng)建slice, 4表示切片的長度, 10標(biāo)識切片的容量
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í)候。
當(dāng)?shù)谝淮魏偷诙蜗蚯衅瑑?nèi)添加元素后,只有切片的長度增加,容量和內(nèi)存地址都沒改變
當(dāng)?shù)谌蜗蚯衅瑑?nèi)添加元素后,長度增加了1,容量變成了之前的2倍,內(nèi)存地址也發(fā)生了改變。
由此我們可以推斷出:
**總結(jié):**當(dāng)切片的元素長度超過了默認(rèn)的容量之后,程序會重新創(chuàng)建一個(gè)底層數(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)
// 輸出兩個(gè)切片調(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)文章
GO項(xiàng)目實(shí)戰(zhàn)之Gorm格式化時(shí)間字段實(shí)現(xiàn)
GORM自帶的time.Time類型JSON默認(rèn)輸出RFC3339Nano格式的,下面這篇文章主要給大家介紹了關(guān)于GO項(xiàng)目實(shí)戰(zhàn)之Gorm格式化時(shí)間字段實(shí)現(xiàn)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-01-01
使用go語言解析xml的實(shí)現(xiàn)方法(必看篇)

