切片,用于表示多个数据(数据集合),可以理解为动态数组
切片是go语言中重要的数据类型,每个切片对象内部都维护着:数据指针,切片长度、切片容量。
type slice struct {
array unsafe.Pointer
len int
cap int
}
在向切片中追加的数据个数大于容量时,内部会自动扩容且每次扩容都是当前容量的2倍,如果当前容量大于1024时那么每次扩容则只增加当前容量的1/4。
// 方式一
var num = []int
// 方式二
var data = []int {11, 22, 33}
// data := []int {11, 22, 33} //简写
// 方式三
// make 只能用于:切片、字典、channel
// 三个参数分别是:1.类型 2.长度 3.容量
var users = make([]string, 1, 3) // 声明一个容量为3的切片,初始化1个默认string类型的值
// 默认创建长度为0 容量为0的切片 并开辟一块内存空间让指针指向该切片
var v1 = new([]int)
var v2 *[]int // 默认开辟一块内存空间并指向nil
var v1 = make([]int, 1, 3) // 如下图,生成一个长度为1,容量为3的切片
fmt.Println(len(num), cap(num))
// 输出的结果为: 1 3
data := make([]int, 3) // 如果只有2个参数,那么它代表 生成一个长度为3,容量为3的切片
fmt.Println(len(data), cap(data))
// 输出的结果为: 3 3
v1 := make([]int, 3)
v2 := append(v1, 66)
append返回一个切片,v1,v2指向同一块内存地址。只是长度发生改变
v1[0] = 99
fmt.Println(v1)
fmt.Println(v2)
/*
输出的结果为:
[99]
[99 66]
*/
引发自动扩容时:
v1 := []int {11, 22, 33}
v2 := append(v1, 44)
当引发自动扩容时,v1和v2就不是指向同一块内存地址。append返回的是一个新开辟内存地址的切片。修改v1的值的时候,v2的值就不会修改
v1[0] = 0
/*
输出的结果为:
[0 22 33]
[11 22 33 44]
*/
可以通过内置函数len()
和cap()
来获取切片的长度和容量
var v1 = make([]int, 1, 3)
fmt.Println(len(num), cap(num))
通过索引获取对应值
info := []string {"august rush", "china", "18"}
info[0]
info[1]
info[2]
如果通过make创建的切片需要注意:
info := make([]string, 2, 5)
info[0]
info[1]
info[2] // 编译报错,因为切片的长度为2,不能以容量来判断
通过索引修改对应值
info[0] = "Thrump is a trouble"
v1 := []int {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
v2 := v1[1:3] // 取 从下标为n开始到下标至m-1之间的值
v3 := v1[:3] // 取 从下标0开始到下标m-1之间的值
v4 := v1[3:] // 去 从下标n开始至集合末尾的之间的值
切片出来的数值与原数值内存指向同一块空间
v := []int {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
v1 := v[1:5]
v2 := v[:5]
v3 := v[4:]
fmt.Println(v1, v2, v3)
// 输出的结果为:[1 2 3 4] [0 1 2 3 4] [4 5 6 7 8 9]
v[4] = 444
fmt.Println(v, v1, v2, v3)
// 输出的结果为:[0 1 2 3 444 5 6 7 8 9] [1 2 3 444] [0 1 2 3 444] [444 5 6 7 8 9]
使用内置函数append()
v := []int {0, 1, 2}
// 方式一:追加一个元素
v1 := append(v, 3)
fmt.Println(v1)
// 输出的结果为:[0 1 2 3]
// 方式二:连续追加多个元素
v2 := append(v, 3, 4, 5, 6)
fmt.Println(v2)
// 输出的结果为:[0 1 2 3 4 5 6]
// 方式三:追加一个切片(需要对新增的切片进行解压操作(...) )
v3 := append(v, []int {8, 9 , 10}...)
fmt.Println(v3)
// 输出的结果为:[0 1 2 8 9 10]
Go没有内置函数进行删除操作,但可通过append()
函数构造一个删除方法
v := []int {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
positionIndex := 3
result := append(v[:positionIndex], v[positionIndex+1:]...)
fmt.Println(result)
// 输出的结果为:[0 1 2 4 5 6 7 8 9]
此方式有个坑:
因为append
函数返回的切片与原切片指向同一块内存空间,索引原切片数据也收到影响,需要注意一下。
v := []int {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
positionIndex := 3
result := append(v[:positionIndex], v[positionIndex+1:]...)
fmt.Println(v)
fmt.Println(result)
/*
输出的结果为:
[0 1 2 4 5 6 7 8 9 9]
[0 1 2 4 5 6 7 8 9]
*/
Go没有内置函数进行插入操作,但可通过append()
函数构造一个插入方法
v := []int {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
insertIndex := 3
// 先声明一个新切片,新切片容量+1 以防止需要扩容
new_v := make([]int, 0, len(v) + 1)
new_v = append(new_v, v[:insertIndex]...)
new_v = append(new_v, 99)
new_v = append(new_v, v[insertIndex:]...)
fmt.Println(v)
fmt.Println(new_v)
/*
输出的结果为:
[0 1 2 3 4 5 6 7 8 9]
[0 1 2 99 3 4 5 6 7 8 9]
*/
方式一
for i:=0;i<len(v);i++ {
fmt.Println(i , v[i])
}
方式二
for index, item := range v {
fmt.Println(index, item)
}
方式一:
var v [][]int
// 输出的结果为:[]
方式二:
var v = [][]int {[]int {1,2}, []int {3, 4}, []int {5, 6}}
// 输出的结果为: [[1 2] [3 4] [5 6]]
v1 := [][2]int {[2]int {1,2}, [2]int{3,4}}
var v = [][]int {[]int {1,2}, []int {3, 4}, []int {5, 6}}
v1 := [][2]int {[2]int {1,2}, [2]int{3,4}}
fmt.Println(v)
fmt.Println(v1)
v[0] = []int {11, 22}
v[1][1] = 222
v1[1][1] = 44
fmt.Println(v)
fmt.Println(v1)
/*
输出的结果为:
[[1 2] [3 4] [5 6]]
[[1 2] [3 4]]
[[11 22] [3 222] [5 6]]
[[1 2] [3 44]]
*/
基于Nginx+Supervisord+uWSGI+Django1.11.1+Python3.6.5构建