数组 数组的声明 var arrayName [arraySize]dataType eg: var array1 [5]int
在声明数组时,必须指定数组名,数组长度和数组元素的类型。
数组的初始化当数组定义好以后,如果没有给数组元素指定值,则所有元素被自动初始化为类型所对应的零值
var array1 [5]int // [0 0 0 0 0]变量的类型零值
在Go语言中,当一个变量被定义为某一种类型后,Go语言会自动初始化其值为零(Zero Value)
零值并不等于空值,而是当变量被声明为某种类型后的默认值
类型 类型零值bool false
int, int8, int16, int32, int64 0
uint, uint8, uint16, uint32, uint64 0
float32, float64 0
complex64, complex128 0+0i
byte, rune 0
string ""
pointer, function, interface, slice, channel, map nil
规律:
数值类型的默认值为0
布尔类型的默认值为false
字符串类型会初始化为空字符串
其他类型为nil,表示没有分配内存地址,使用前必须人为分配内存地址
(1)在定义数组时对数组元素赋初值
var array1 = [5]int{0, 1, 2, 3, 4} // [0 1 2 3 4]注意:花括号中的元素个数不得超过arraySize
(2)可以只给一部分元素赋初值
var array1 = [5]int{0, 1, 2} // [0 1 2 0 0]注意:未赋值的默认初始化为类型零值
(3)可以由初始化列表决定数组长度
var array1 = [...]int{0, 1, 2, 4, 5, 6} // [0 1 2 4 5 6]注意:
该例中数组长度为 ··· 标识符,表示没有指定数组长度,数组长度由初始化列表决定
··· 标识符不可省略,否则将变成后文将要讲的切片
(4)按照下标初始化元素
var array1 = [5]int{0: 5, 4: 5} // [5 0 0 0 5] 数组元素的访问和遍历访问
数组元素按照下标进行访问,下标从0开始,可以是整型常量或者整型表达式
var array1 = [8]int{1, 2, 3, 4, 5, 6, 7, 8} fmt.Println(array1[0], array1[6], array1[2*3]) // 1 7 7遍历
(1)for语句
var array1 = [8]int{1, 2, 3, 4, 5, 6, 7, 8} for i := 0; i < 8; i++ { fmt.Printf("%d ", array1[i]) } // 1 2 3 4 5 6 7 8(2)for range语句
var array1 = [3]int{1, 2, 3} for i, v := range array1 { fmt.Printf("index is %d, value is %d.\n", i, v) } // index is 0, value is 1. // index is 1, value is 2. // index is 2, value is 3.range 具有两个返回值,第一个返回值i是数组元素的下标,第二个返回值v是数组元素的值
二维数组 var array2 = [3][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}, {}} // 三行四列 fmt.Println(array2) // [[1 2 3 4] [5 6 7 8] [0 0 0 0]] 切片切片(slice)是数组的一个引用,它会生成一个指向数组的指针,并通过切片长度关联到底层数组部分或者全部元素。
切片中的元素是可以动态增加,删除的,所以切片通常被用来实现变长数组。
切片的数据结构原型定义如下(Go/src/runtime/slice.go)
type slice struct { array unsafe.Pointer // 指向被引用的底层数组的指针 len int // 切片中元素的个数 cap int // 切片分配的存储空间 } 切片的声明与创建(1)直接创建切片
var slice1 = []int{1, 2, 3, 4} fmt.Println(slice1, len(slice1), cap(slice1)) // [1 2 3 4] 4 4(2)基于底层数组创建切片
在创建切片时,可以基于一个底层数组,切片可以只使用数组的一部分元素,或者所有元素
var slice1 []int // 注意和数组的区别 // 当一个切片定义好以后,如果还没有被初始化,默认值为nil fmt.Println(slice1, len(slice1), cap(slice1)) // 使用len()获取切片的长度,使用cap()获取切片的容量 // [] 0 0 // 使用slice1 = array1[start:end]引用底层数组来初始化切片 // 即切片引用数组元素由array1[start]到array2[end],但不包括array1[end] // start默认值为0,end默认值为len(array1) var array1 = [5]int{1, 2, 3, 4, 5} slice1 = array1[:] fmt.Println(slice1, len(slice1), cap(slice1)) // [1 2 3 4 5] 5 5 var slice2 []int slice2 = array1[1:4] fmt.Println(slice2, len(slice2), cap(slice2)) // [2 3 4] 3 4(3)使用make函数创建切片
var sliceName = make(sliceType,len,cap) // 使用make()函数创建切片时,可以指定切片的元素个数,并且为切片元素预留存储空间 // 在后文切片的操作部分,我们会讲解指定(预估)切片容量的好处 eg: var slice1 = make([]int, 3, 5) // 切片的元素个数为3,切片的容量为5 fmt.Println(slice1, len(slice1), cap(slice1)) // [0 0 0] 3 5 切片元素的访问和遍历这个和数组元素的访问以及遍历是一样的
切片的内置操作(1)len()
获取切片中元素的个数
(2)cap()
获取切片的容量大小
(3)append()
使用append()函数向切片尾部添加新元素,这些元素保存到底层数组