数组
Go语言中数组是值语义,一个数组变量即表示整个数组,它并不是隐式的指向第一个元素的指针(比如C语言的数组),而是一个完整的值。当一个数组变量被赋值或者被传递的时候,实际上会复制整个数组。如果数组较大的话,数组的赋值也会有较大的开销。为了避免复制数组带来的开销,可以传递一个指向数组的指针,但是数组指针并不是数组。
Go数组声明需要指定元素类型以及元素个数,格式如下:
var variable_name [SIZE] variable_type
var values [10] int
Go使用大括号初始化数组中的元素,如果元素没有指定初始值,默认为零值。
func main() {
var values=[10] int{1,2,3,4}
println(values[0])//1
println(values[4])//0
}
如果数组有初始值,数组大小使用…代替,Go将会根据元素个数来设置数组大小。
func main() {
var values=[...] int{1,2,3,4}
println(len(values))//4
}
Go支持多维数组,格式如下:
var variable_name [SIZE1][SIZE2]...[SIZEN] variable_type
下面代码中的values是一个3行4列的二维数组,由3个长度为4的数组组成。
func main() {
var values=[3][4] int{
{0, 1, 2, 3} ,
{4, 5, 6, 7} ,
{8, 9, 10, 11},
}
println(values[1][2])//6
}
切片
Go 数组的长度不可改变,而切片的长度是不固定的,可以理解为动态数组,其底层数据为数组,声明格式如下:
var identifier []type
切片默认值为nil,使用内置函数make创建切片,其中capacity为可选参数。
make([]type, length, capacity)
获取切片长度,容量:
func main() {
var values=[] int{1,2,3,4}
println(len(values))
println(cap(values))
}
使用内置函数append追加数据并返回新的切片,参数为切片时需要加…。
func main() {
var values [] int
values=append(values,1)
values=append(values,2,3,4)
values=append(values,[]int{5,6,7}...)
println(len(values))
}
使用内置函数copy将一个切片的数据拷贝到另一个切片,拷贝的长度为这两个切片长度的最小值。
func main() {
var values1=[] int{1,2,3,4}
var values2=[] int{4,5}
copy(values1,values2)
fmt.Println(values1)//4,5,3,4
values1=[] int{1,2,3,4}
values2=[] int{4,5}
copy(values2,values1)
fmt.Println(values2)//1,2
}
可以通过设置下限及上限来截取切片 [lower-bound:upper-bound],返回的新切片与原有切片共享底层数组。
func main() {
var values=[] int{0,1,2,3,4,5,6,7,8}
//全部元素
fmt.Println(values[:])//[0 1 2 3 4 5 6 7 8]
//包含下限2,但不包含上限5
fmt.Println(values[2:5])//[2 3 4]
//默认下限为0
fmt.Println(values[:2])//[0 1]
//默认上限为len(values)
fmt.Println(values[3:])//[3 4 5 6 7 8]
newArray:=values[2:5]
newArray[0]=1000
fmt.Println(values)//[0 1 1000 3 4 5 6 7 8]
}
切片清空有两种方式,赋值为[:0]或者nil,前者清空后再添加数据会重用上次分配的内存,后者需要重新分配内存。
func main() {
values1:=[] int{0,1,2,3,4,5,6,7,8}
fmt.Printf("%p\n",values1)//0xc00005c050
values1=values1[:0]
fmt.Printf("%p\n",values1)//0xc00005c050
fmt.Println(cap(values1))
values2:=[] int{0,1,2,3,4,5,6,7,8}
fmt.Printf("%p\n",values2)//0xc00005c0a0
values2=nil
values2=append(values2,2)
fmt.Printf("%p\n",values2)//0xc0000560a8
fmt.Println(cap(values2))
}
使用binary库可以指定小端序还是大端序写入数字到byte切片
func main() {
values:=[] byte{0,1,2,3,4,5,6,7,8}
binary.BigEndian.PutUint16(values,0x1234)
binary.BigEndian.PutUint16(values[2:],0x5678)
fmt.Println(values)//[18 52 86 120 4 5 6 7 8]
}