Go语言入门10:数组

Keywords: #技术 #Golang #Go 入门笔记
Table of Contents

Go 语言入门基础学习笔记之 Go 语言的数组

golang

数组

声明数组

Go 语言数组声明需要指定元素类型及元素个数。

var arrayName [size]dataType

其中,arrayName 是数组的名称,size 是数组的大小,dataType 是数组中元素的数据类型。比如:

// 数组 balance 长度为 10 类型为 float32
var balance [10]float32

初始化数组

在声明时,数组中的每个元素都会根据其数据类型进行默认初始化,对于整数类型,初始值为 0

var numbers [5]int
// 或者 函数内使用
numbers := [5]int{}

还可以使用初始化列表来初始化数组的元素:

var numbers = [5]int{1, 2, 3, 4, 5}

另外,还可以使用 := 简短声明语法来声明和初始化数组(函数内使用):

numbers := [5]int{1, 2, 3, 4, 5}

注意:在 Go 语言中,数组的大小类型的一部分,因此不同大小的数组是不兼容的,也就是说 [5]int 和 [10]int 是不同的类型。使用 %T 打印出来的数据类型也是如 [10]int 一样的形式。

因此,在函数中传递数组类型时,一定要带上相对应的类型! 向函数传递数组

初始化数组中 {} 中的元素个数不能大于 [] 中的数字。

如果数组长度不确定,可以使用 ... 代替数组的长度,编译器会根据元素个数自行推断数组的长度

var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
// 或者
balance := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

如果忽略 [] 中的数字不设置数组大小,Go 语言也会根据元素的个数来设置数组的大小(等同于 [...]),事实上这是 Go 语言中的切片

如果设置了数组的长度,我们还可以通过指定下标初始化元素:

//  将索引为 1 和 3 的元素初始化
balance := [5]float32{1:2.0,3:7.0}

访问数组元素

数组元素可以通过索引(位置)来读取。

var salary float32 = balance[9]

多维数组

Go 语言支持多维数组,以下为常用的多维数组声明方式:

var variable_name [SIZE1][SIZE2]...[SIZEN] variable_type

比如三维整型数组声明:

var threedim [5][10][4]int

左到右维数依次增加

二维数组

var arrayName [ x ][ y ] variable_type

其中 variable_type 为 Go 语言的数据类型,arrayName 为数组名,二维数组可认为是一个表格,x 为行,y 为列。比如声明一个三行四列整型数组:

var a [3][4]int

image.png

package main

import "fmt"

func main() {
    // Step 1: 创建数组
    values := [][]int{}

    // Step 2: 使用 append() 函数向空的二维数组添加两行一维数组
    row1 := []int{1, 2, 3}
    row2 := []int{4, 5, 6}
    values = append(values, row1)
    values = append(values, row2)

    // Step 3: 显示两行数据
    fmt.Println("Row 1")
    fmt.Println(values[0])
    fmt.Println("Row 2")
    fmt.Println(values[1])

    // Step 4: 访问第一个元素
    fmt.Println("第一个元素为:")
    fmt.Println(values[0][0])
}

// 输出结果
Row 1
[1 2 3]
Row 2
[4 5 6]
第一个元素为
1

初始化二维数组

多维数组可通过大括号来初始值。

a := [3][4]int{  
 {0, 1, 2, 3} ,   /*  第一行索引为 0 */
 {4, 5, 6, 7} ,   /*  第二行索引为 1 */
 {8, 9, 10, 11},   /* 第三行索引为 2 */
}

注意:以上代码中倒数第二行的 } 必须要有逗号,因为最后一行的 } 不能单独一行,如果不加逗号也可以写成这样:

a := [3][4]int{  
{0, 1, 2, 3} ,   /*  第一行索引为 0 */
{4, 5, 6, 7} ,   /*  第二行索引为 1 */
{8, 9, 10, 11}}   /* 第三行索引为 2 */
// 或者
a := [3][4]int{{0, 1, 2, 3},{4, 5, 6, 7},{8, 9, 10, 11}}
package main

import "fmt"

func main() {
    // 创建二维数组
    sites := [2][2]string{}

    // 向二维数组添加元素
    sites[0][0] = "Google"
    sites[0][1] = "Runoob"
    sites[1][0] = "Taobao"
    sites[1][1] = "Weibo"

    // 显示结果
    fmt.Println(sites)
}

// 输出结果
[[Google Runoob] [Taobao Weibo]]

访问二维数组

维数组通过指定坐标来访问,如数组中的行索引列索引

// 访问二维数组的第3行第4个元素
value := a[2][3]
// 或者
var value int = a[2][3]
package main

import "fmt"

func main() {
    // 创建空的二维数组
    animals := [][]string{}

    // 创建三一维数组,各数组长度不同
    row1 := []string{"fish", "shark", "eel"}
    row2 := []string{"bird"}
    row3 := []string{"lizard", "salamander"}

    // 使用 append() 函数将一维数组添加到二维数组中
    animals = append(animals, row1)
    animals = append(animals, row2)
    animals = append(animals, row3)

    // 循环输出
    for i := range animals {
        fmt.Printf("Row: %v\n", i)
        fmt.Println(animals[i])
    }
}

// 输出结果
Row: 0
[fish shark eel]
Row: 1
[bird]
Row: 2
[lizard salamander]

向函数传递数组

Go 语言中的数组是值类型,因此在将数组传递给函数时,实际上是传递数组的副本

由于 Go 语言中数组的大小也是类型的一部分,因此在函数参数传递时应该带上数组的大小,并且不能将不同大小的数组进行传递。因此在实际工作中,常常使用动态数组或者说是切片 Slice

如果你想向函数传递数组参数,你需要在函数定义时,声明形参为数组,我们可以通过以下两种方式来声明:

  1. 形参设定数组大小
func myFunction(param [10]int) {
    ....
}
  1. 形参未设定数组大小
func myFunction(param []int) {
    ....
}

如果你想要在函数内修改原始数组,可以通过传递数组的指针来实现。比如:

package main

import "fmt"

// 函数接受一个数组作为参数
func modifyArray(arr [5]int) {
    for i := 0; i < len(arr); i++ {
        arr[i] = arr[i] * 2
    }
}

// 函数接受一个数组的指针作为参数
func modifyArrayWithPointer(arr *[5]int) {
    for i := 0; i < len(*arr); i++ {
        (*arr)[i] = (*arr)[i] * 2
    }
}

func main() {
    // 创建一个包含5个元素的整数数组
    myArray := [5]int{1, 2, 3, 4, 5}

    fmt.Println("Original Array:", myArray)

    // 传递数组给函数,但不会修改原始数组的值
    modifyArray(myArray)
    fmt.Println("Array after modifyArray:", myArray)

    // 传递数组的指针给函数,可以修改原始数组的值
    modifyArrayWithPointer(&myArray)
    fmt.Println("Array after modifyArrayWithPointer:", myArray)
}

// 输出结果
Original Array: [1 2 3 4 5]
Array after modifyArray: [1 2 3 4 5]
Array after modifyArrayWithPointer: [2 4 6 8 10]

当然,在实际工作中,以上利用数组指针传递参数的方法并不常用,其完全可以使用切片 Slice 来替代,切片是一种引用数据类型,直接传递的就是指针,更加方便。


参考课程:

  1. 8小时转职Golang工程师
  2. Go语言教程 | 菜鸟教程