Go基础(三)数组

108 阅读3分钟

数组的初始化

数组是块连续的内存空间,在声明的时候必须指定长度,且长度不能改变。所以数组在声明的时候就可以把内存空间分配好,并赋上默认值,即完成了初始化。 array.png

一维数组初始化

var arr1 [5]int = [5]int{} //数组必须指定长度和类型,且长度和类型指定后不可改变
var arr2 = [5]int{}
var arr3 = [5]int{3, 2} //给前2个元素赋值
var arr4 = [5]int{2: 15, 4: 30} //指定index赋值
var arr5 = [...]int{3, 2, 6, 5, 4}//根据{}里元素的个数推断出数组的长度
var arr6 = [...]struct {
    name string
    age int
}{{"Tom", 18}, {"Jim", 20}} //数组的元素类型由匿名结构体给定

二维数组初始化

//5行3列,只给前2行赋值,且前2行的所有列还没有赋满
var arr1 = [5][3]int{{1}, {2, 3}}
//第1维可以用...推测,第2维不能用...
var arr2 = [...][3]int{{1}, {2, 3}}

访问数组里的元素

  • 通过index访问

    • 首元素 arr[0]
    • 末元素 arr[len(arr)-1]
  • 访问二维数组里的元素

    • 位于第三行第四列的元素 arr2

数组的遍历

//遍历数组里的元素
for i, ele := range arr {
    fmt.Printf("index=%d, element=%d\n", i, ele)
}
//或者这样遍历数组
for i := 0; i < len(arr); i++ { //len(arr)获取数组的长度
    fmt.Printf("index=%d, element=%d\n", i, arr[i])
}
//遍历二维数组
for row, array := range arr { //先取出某一行
    for col, ele := range array { //再遍历这一行
        fmt.Printf("arr[%d][%d]=%d\n", row, col, ele)
    }
}

  通过for range遍历数组时取得的是数组里每一个元素的拷贝。

arr := [...]int{1, 2, 3}
for i, ele := range arr { //ele是arr中元素的拷贝
   arr[i] += 8 //修改arr里的元素,不影响ele
   fmt.Printf("%d %d %d\n", i, arr[i], ele)
   ele += 1 //修改ele不影响arr
   fmt.Printf("%d %d %d\n", i, arr[i], ele)
}
for i := 0; i < len(arr); i++ {
   fmt.Printf("%d %d\n", i, arr[i])
}

cap和len的区别

在数组上调用cap()函数表示capacity容量,即给数组分配的内存空间可以容纳多少个元素;len()函数代表length长度,即目前数组里有几个元素。由于数组初始化之后长度不会改变,不需要给它预留内存空间,所以len(arr)==cap(arr)。对于多维数组,其cap和len指第一维的长度。   数组的长度和类型都是数组类型的一部分,函数传递数组类型时这两部分都必须吻合。go语言没有按引用传参,全都是按值传参,即传递数组实际上传的是数组的拷贝,当数组的长度很大时,仅传参开销都很大。如果想修改函数外部的数组,就把它的指针(数组在内存里的地址)传进来。

//参数必须是长度为5的int型数组(注意长度必须是5)
func update_array1(arr [5]int) {
  fmt.Printf("array in function, address is %p\n", &arr[0])
  arr[0] = 888

}

func update_array2(arr *[5]int) {
  fmt.Printf("array in function, address is %p\n", &((*arr)[0]))
  arr[0] = 888 //因为传的是数组指针,所以直接在原来的内存空间上进行修改
}

数组的传参

func basic() {
   var arr1 [5]int = [5]int{}
   var arr2 = [5]int{}
   var arr3 = [5]int{1, 2, 4}
   var arr4 = [5]int{2: 8, 3: 8} //:前面是inx
   var arr5 = [...]int{1, 2, 4}
   fmt.Println(arr1)
   fmt.Println(arr2)
   fmt.Println(arr3)
   fmt.Println(arr4)
   fmt.Println(arr5)
   arr4[len(arr4)-1] = 9
   fmt.Println(arr4)
}

func mean(arr [5]int) float64 {
   var sum int

   for i := 0; i < len(arr); i++ {
      sum += arr[i]
   }

   for _, value := range arr {
      sum += value
   }
   return float64(sum) / float64(len(arr))

}

func arrPoint(arr *[5]int) {
   fmt.Printf("%p\n", arr)
   fmt.Println(arr[0])
   arr[0] += 10
   fmt.Println(arr[0])
}

func main() {
   basic()
   var arr = [5]int{1, 2, 3, 4, 5}
   a := mean(arr)
   fmt.Println(a)
   arrPoint(&arr)
   fmt.Printf("%p\n", &arr)
   fmt.Println(arr[0])
}