Go的切片:
package main
import "fmt"
//切片slice,是对数组的一个连续片段的引用,所以切片是一个引用类型,像python中list类型
//Go语言中切片的内部结构包含地址,大小和容量,切片一般用于快速地操作一块数据集合
//从数组或切片生成新的切片
//格式:slice[开始位置:结束位置]
//slice:表示目标切片对象;开始位置:对应目标的切片对象的索引;结束位置:对应目标切片结束的索引
//根据索引位置取切片 slice 元素值时,取值范围是(0~len(slice)-1),超界会报运行时错误,生成切片时,结束位置可以填写 len(slice) 但不会报错。
func main() {
var a=[3]int{1,2,3}
//从切片开始索引到不包含结束位置对应的索引
fmt.Println(a,a[1:3]) //[1 2 3] [2 3]
//取索引为0~2 不包含索引为2的
fmt.Println(a[:2]) //[1 2]
//取索引为1且包含1的后面所有元素
fmt.Println(a[1:]) //[2 3]
slice()
makesilce()
}
//声明新的切片
//声明新的切片后,可以使用 append() 函数向切片中添加元素。
func slice() {
//声明字符串切片
var strList[]string
//声明整型切片
var numList[]int
//声明一个空切片
var numListEmpty=[]int{}
//输出3个切片
fmt.Println(strList,numList,numListEmpty) //[] [] []
//输出3个切片大小
fmt.Println(len(strList),len(numList),len(numListEmpty)) //0 0 0
//切片判定空的结果
//声明但未使用的切片的默认值是 nil,strList 和 numList 也是 nil,所以和 nil 比较的结果是 true。
//切片是动态结构,只能与 nil 判定相等,不能互相判定相等。
fmt.Println(strList==nil) //true
fmt.Println(numList==nil) //true
fmt.Println(numListEmpty==nil) //false:numListEmpty 已经被分配了内存,只是还没有元素
}
//使用make()函数构造切片:make( []Type, size, cap )
//其中 Type 是指切片的元素类型,size 指的是为这个类型分配多少个元素,cap 为预分配的元素数量,这个值设定后不影响 size,只是能提前分配空间,降低多次分配空间造成的性能问题。
//使用 make() 函数生成的切片一定发生了内存分配操作,但给定开始与结束位置(包括切片复位)的切片只是将新的切片结构指向已经分配好的内存区域,设定开始与结束位置,不会发生内存分配操作。
func makesilce() {
a:=make([]int,2,20)
fmt.Println(a)
}
append方法
package main
import (
"fmt"
)
//append()为切片添加元素
//切片(slice)是对数组的一个连续片段的引用,所以切片是一个引用类型,像python中的list对象
func main() {
var a []int
a=append(a,1) //追加一个元素
a=append(a,2,3,4) //追加多个元素,手动解包
fmt.Println(a) //[1 2 3 4]
//给a追加一个切片,切片需要解包
a=append(a,[]int{1,2,3}...)
fmt.Println(a)//[1 2 3 4 1 2 3]
List1()
Frist()
Chian()
}
//切片在使用append函数为切片添加元素时,空间不足时会自动扩容
func List1() {
//声明切片
var list[]int
for i:=0;i<10 ;i++ {
list=append(list,i)
//println会根据你输入格式原样输出,printf需要格式化输出并带输出格式;
//%d以10为基数
//%p以16为基础的表示法,前导0x
fmt.Printf("len: %d cap: %d pointer: %p\n",len(list),cap(list),list)
}
}
/*
长度 容量 内存指针
len: 1 cap: 1 pointer: 0xc00008a080
len: 2 cap: 2 pointer: 0xc00008a0a0
len: 3 cap: 4 pointer: 0xc00008c060
len: 4 cap: 4 pointer: 0xc00008c060
len: 5 cap: 8 pointer: 0xc000090080
len: 6 cap: 8 pointer: 0xc000090080
len: 7 cap: 8 pointer: 0xc000090080
len: 8 cap: 8 pointer: 0xc000090080
len: 9 cap: 16 pointer: 0xc000092000
len: 10 cap: 16 pointer: 0xc000092000
随着添加元素的增加,切片长度len不等于容量cap,内存也随之变化
*/
//在切片开头添加元素
func Frist() {
//在切片开头添加元素一般都会导致内存的重新分配,而且会导致已有元素全部被复制 1 次,
// 因此,从切片的开头添加元素的性能要比从尾部追加元素的性能差很多。
var a=[]int{1,2,3,4}
a=append([]int{0},a...) //在开头添加1个元素
fmt.Println(a)//[0 1 2 3 4]
a=append([]int{4,5,6,7},a...) //在开头添加一个切片
fmt.Println(a)//[4 5 6 7 0 1 2 3 4]
}
//因为 append 函数返回新切片的特性,所以切片也支持链式操作,
// 我们可以将多个 append 操作组合起来,实现在切片中间插入元素
//切片的链式操作
func Chian() {
var b =[]int{1,2,3,4,5}
//每个添加操作中的第二个 append 调用都会创建一个临时切片,并将 a[i:] 的内容复制到新创建的切片中,
// 然后将临时创建的切片再追加到 a[:i] 中。
//先在b[2:]开头处添加一个元素,然后再将整个切片添加到b[:2]后边
b=append(b[:2],append([]int{9},b[2:]...)...) //在第i个位置插入x
fmt.Println(b) //[1 2 9 3 4 5]
}