数组

定义数组的语法

声明固定长度的空数组

package main

import "fmt"

func main() {
    // 固定长度的数组
    var myArray1 [10] int

    // 遍历空数组的初始值
    for i := 0 ; i<len(myArray1); i++ {
        fmt.Println(myArray1[i])
    }
}
  • 第7行定义一个固定长度为10的数组
  • 第10-12行循环遍历数组中每个元素中的值,并且打印出来。

运行结果:
image.png
可以看到,当声明了一个空数组,元素的初始化值都为0。

声明固定长度的数组并同时赋值

package main

import "fmt"

func main() {
    // 声明数组的同时赋值,没有赋值的部分初始化值依旧为空。
    myArray2 := [10] int {1,2,3,4} // 声明一个长度为10的空数组,并且赋值1,2,3,4,其余未赋值的元素值为0

    // 遍历打印数组的每个元素
    for index, value := range myArray2 {
        fmt.Println("index=",index, ", value = ",value)
    }
}
  • 第7行声明数组myArray2时同时赋值1,2,3,4给前四个元素,后面的默认值为0。
  • 10-12行使用for循环打印数组的每个元素

运行结果:
image.png

声明动态数组

动态数组的声明就是将[]内为空

package main

import "fmt"

func main()  {
    myArray := []int{1,2,3,4}  //声明动态数组,也叫作切片,[]为空表示动态数组

    fmt.Printf("myArray type is %T\n", myArray)  // 打印切片的数据类型
}

动态数组的声明为指针指向一段内存地址,这个在下面函数传递动态数组有说明。

查看数组的数据类型

固定数组的数据类型

package main

import "fmt"

func main() {
    // 固定长度的数组
    var myArray1 [10] int
    // 声明数组的同时赋值,没有赋值的部分初始化值依旧为空。
    myArray2 := [10] int {1,2,3,4} // 声明一个长度为10的空数组,并且赋值1,2,3,4,其余未赋值的元素值为0
    myArray3 := [4] int {11,22,33,44}

    fmt.Printf("myArray1 types= %T\n", myArray1)
    fmt.Printf("myArray2 types= %T\n", myArray2)
    fmt.Printf("myArray3 types= %T\n", myArray3)

}

运行结果:
image.png
可以看到固定长度的数组的数据类型由数组长度和数组元素类型组成,注意:[4]int和[10]int不是同种数据类型

动态数组/切片的数据类型

动态数组/切片的数据类型为[]int
image.png

固定长度数组传参

  • 函数中将数组作为参数传递时要注意传递的数组声明的形参数据类型要相同
  • 注意:不能将长度为[10]int的数组传递给参数的数据类型为[4]int的函数,会报错。
  • 固定长度数组传参属于值拷贝,也就是函数体内复制了实参的一份值,不能够修改实参原有的数。

例如传递一个数据类型为[4]int的数组作为参数:

package main

import "fmt"

func printArray(myArray [4]int) {  // 固定长度的数组传递是值传递
    for index,value := range myArray {
        fmt.Println("index = ", index,", value= ",value)
    }
}

func main() {
    myArray3 := [4] int {11,22,33,44}
    printArray(myArray3)
}
  • 第5行规定函数参数的数据类型为[4]int
  • 第13行调用定义的printArray函数

运行结果:
image.png

动态数组的传参

func printArray2(myArray []int) {
    // _表示匿名的变量
    for _, value := range myArray{
        fmt.Println("value = ",value)
    }
}

func main()  {
    myArray := []int{1,2,3,4}  //声明动态数组,也叫作切片,[]为空表示动态数组

    fmt.Printf("myArray type is %T\n", myArray)  // 打印切片的数据类型

    printArray2(myArray)
}
  • 1-6行声明了一个函数用来接收动态数组,并且循环打印数组的值
  • 第13行调用函数

运行结果:
image.png

动态数组为引用传递

不同于固定数组为形参时的值传递,动态数组为形参时为引用传递,也就是函数体内可以直接修改实参的数据。
例如:

package main

import "fmt"

func printArray2(myArray []int) {
    // 引用传递
    // _表示匿名的变量
    for _, value := range myArray{
        fmt.Println("value = ",value)
    }
    myArray[0] = 1001 // 在函数体内修改动态数组的值
}

func main()  {
    myArray := []int{1,2,3,4}  // 声明动态数组,也叫作切片,[]为空表示动态数组

    fmt.Printf("myArray type is %T\n", myArray)  // 打印切片的数据类型

    printArray2(myArray)
    fmt.Println("=====================")

    for _,value := range myArray{
        fmt.Println("value = ",value)
    }
}
  • 第11行在函数中修改传递过来的数组里的值。
  • 22-24行循环打印修改之后的原数组

运行结果:
image.png
可以看到原数组的值收到了函数中修改操作的影响。

  • 也就是说动态数组作为参数的传递是引用传递,相当于将实参的内存地址传递给函数。

    • 函数体内对动态数组操作是直接针对数组对应的内存地址去操作,因此在函数体外的原数组也会受到影响。



for循环介绍

传统for循环

传统for循环的语法和C语言的FOR一样:
for init; condition; post { }

  • init: 一般为赋值表达式,给控制变量赋初值;
  • condition: 关系表达式或逻辑表达式,循环控制条件;
  • post: 一般为赋值表达式,给控制变量增量或减量。

例如:

    // 遍历空数组的初始值
    for i := 0 ; i<len(myArray1); i++ {
        fmt.Println(myArray1[i])
    }

for range

格式如下:

    for index, value := range myArray2 {
        fmt.Println("index=",index, ", value = ",value)
    }
  • 通过range格式的for循环,可以将元素的索引下标,和对应的元素的值都遍历出来。
最后修改:2024 年 03 月 13 日
如果觉得我的文章对你有用,请随意赞赏