python支持序列类型的数据进行切片,这种方式非常的便捷。
go语言中的数据容器只有数组,但是由于go有点底层,没有办法实现数组的切片,于是添加了一种新的数据类型,叫做切片slice,用于解决数组切片的问题。
简述go语言的切片,实际上为一个结构体,结构体源码如下:
type slice struct { array unsafe.Pointer //一个指向数组的指针 len int cap int }
go中的切片与数组是不分家的,切片依靠的是数组,由此实现数组的切片,但是切片的功能更加强大,除了实现数组的切片,还能增加长度。即:切片可以实现已经存在的数组的切片;也能自己开辟连续的内存空间之后自定义数组进行切片,此时就可以无限的增加数组的长度,实现数组长度不可变的难题。
目录
一,字面量形式的切片
代码如下:
s := []int{1, 2, 3} //一句代码完成声明和初始化两个工作
[]里面不写长度,就是一个切片。实际上是:1,先创建一个含有数据1,2,3的数组;2,利用切片结构体创建切片,令array_pointer指向数组首地址,然后令len=cap=len(array)=3;3,使用[start:stop]来切片访问数据。
实际上go利用[start:end:upper_bound]的形式,len=end-start,cap=upper_bound-start。upper_bound默认为全部数字个数。
二,切已经存在的数组形成切片
先字面量形式定义一个数组,再用切片去切这个数组。此时切片的len必须小于被切数组的长度,切片的len必须小于cap。cap会根据len自动的增加以确保越界报错。切片的array_pointer指向的是start数据的内存地址。
package main
import (
"fmt"
)
func main() {
arr := [5]int{1, 2, 3, 4, 5}
fmt.Println(arr)
slice := arr[0:3]
fmt.Println(slice)
}
三,使用make开辟内存并自定义切片
make(array_point,len,cap),返回一个切片类型的首地址。这个时候他就成了一个可以自定义数据内容的切片。
package main
import "fmt"
func main() {
s2 := make([]int, 6, 8) // 使用 make 创建,指定 len 和 cap 值。
s2[0], s2[1], s2[2] = 1, 2, 3
fmt.Println(s2, len(s2), cap(s2))
s3 := make([]int, 6) // 省略 cap,相当于 cap = len。
fmt.Println(s3, len(s3), cap(s3))
}
// [1 2 0 3 0 0] 6 8
// [0 0 0 0 0 0] 6 6
四,append函数实现切片扩容
append(slice_name,new_values or another slice)。当追加数据时len<cap则会再原来的底层数组进行追加;否则make一块新的内存空间之后将之前的的数组拷贝过去再追加。追加过程go会确保len<cap,以免越界造成内存数据篡改。
package main
import (
"fmt"
)
func main() {
arr := [5]int{1, 2, 3, 4, 5}
fmt.Println(arr)
slice := arr[:]
slice = append(slice, 6, 7, 8)
fmt.Println(slice)
}