Golang学习笔记-数组和切片

数组

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]
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页