赞
踩
Slice(切片)是抽象在 Array(数组)之上的特殊的数据类型类型,在了解slice之前需要先了解一下Array的情况。
Array数组就是 Golang 的基本数据类型中的数字,是一种顺序存储结构。
func main() {
nums := [4]int{}
nums[0] = 1
nums[2] = 3
fmt.Printf("nums: %v\n", nums)
fmt.Printf("nums[2]: %d\n", nums[2])
}
输出结果
在使用的时候需要指定长度和存储元素类型。数组在声明后,其元素的初始值(也就是零值)为 0。并且该变量可以直接使用,不需要特殊操作。底层数据存储为一段连续的内存空间,通过固定的索引值(下标)进行检索。
需要注意的是数组的长度是固定的,它的长度是类型的一部分,因此 [3]int 和 [4]int 在类型上是不同的
Slice 是对 Array 的抽象,Slice 和 Array 不一样,它不需要指定长度。使用更加的灵活,能够自动扩容。
func main() {
nums := [4]int{}
nums[0] = 1
nums[2] = 3
slice := nums[:]
fmt.Printf("slice: %v", slice)
}
输出结果为
它的存储结构这样的,共分为三部分
len 可以不等于 cap,但必须大于或等于 len,否则会导致 panic
func main() {
nums := [4]int{}
nums[0] = 1
nums[2] = 3
slice := nums[0:3]
fmt.Printf("slice: %v, len: %d, cap: %d", slice, len(slice), cap(slice))
}
数据结构是这样的,只取了 nums 的三个元素的指针
创建切片除了上面的方式,还有另外一种不常见的方式,我们简单看一下源码
// MakeSlice creates a new zero-initialized slice value // for the specified slice type, length, and capacity. func MakeSlice(typ Type, len, cap int) Value { if typ.Kind() != Slice { panic("reflect.MakeSlice of non-slice type") } if len < 0 { panic("reflect.MakeSlice: negative len") } if cap < 0 { panic("reflect.MakeSlice: negative cap") } if len > cap { panic("reflect.MakeSlice: len > cap") } s := unsafeheader.Slice{Data: unsafe_NewArray(typ.Elem().(*rtype), cap), Len: len, Cap: cap} return Value{typ.(*rtype), unsafe.Pointer(&s), flagIndir | flag(Slice)} }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。