欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Go 语言 数组的使用

程序员文章站 2024-03-02 16:18:16
...

Go 语言 数组的使用

一、数组的介绍:

数组可以存放多个同一类型的数据。数组也是一种数据类型,在Go 中,数组是值类型

举个简单栗子

package main

import "fmt"

func main() {
	// 数组的快速使用
	// 1. 定义一个数组
	var array [6]float64

	// 2.给数组每个元素赋值, 元素下标是从0开始的
	array[0] = 1.0
	array[1] = 2.0
	array[2] = 3.0
	array[3] = 4.0
	array[4] = 5.0
	array[5] = 6.0

	// 3.遍历求出数组的总数量
	total := 0.0
	for i := 0; i < len(array); i++ {
		total += array[i]
	}

	// 4.求出平均值
	avg := fmt.Sprintf("%.2f", total / float64(len(array)))  // 因为数组定义的是float类型, 运算时类型应相同
	fmt.Printf("数组的总值:%v, 数组的平均值:%v", total, avg)
}

// 输出结果:
数组的总值:21, 数组的平均值:3.50

二、数组的定义、布局:

数组的定义

var 数组名 [数组大小]数据类型

栗子如下

var arrayName [6]int

// 定义一个数组, 名为 arrayName;数组大小为6;数据类型为int;

赋初值:数组名[下标] = 值

栗子如下

arrayName[0] = 1

arrayName[1] = 2

// 赋初值:数组名为:arrayName 下标为0, 赋值为1,以此类推

当我们定义完数组后,如果没有赋初值,那么数组各个元素都有默认值 0

举个栗子

package main

import "fmt"

func main() {
	// 当我们定义完数组后,如果没有赋初值, 那么数组各个元素的默认值都为0
	var intArray[3]int
	fmt.Println("数组的默认值:", intArray)
}
// 输出结果:
数组的默认值: [0 0 0]

数组在内存布局

举个栗子:

package main

import "fmt"

func main() {
	// 数组在内存中布局的讲解
	var intArray[3]int64
	intArray[0] = 10
	intArray[1] = 20
	intArray[2] = 30
	fmt.Println(intArray)
	fmt.Printf("intArray的地址是:%p; intArr[0] 地址是:%p; intArr[1] 地址是:%p; intArr[2] 地址是:%p; ",
		&intArray, &intArray[0], &intArray[1], &intArray[2])
}
// 输出结果:
[10 20 30]
intArray的地址是:0xc00000e360; intArr[0] 地址是:0xc00000e360; intArr[1] 地址是:0xc00000e368; intArr[2] 地址是:0xc00000e370; 

如图所示:
Go 语言 数组的使用
总结:

  1. 数组的地址可通过数组名来获取,&intArray;
  2. 数组的第一个元素地址,就是数组首地址
  3. 数组的每个元素地址间隔,是根据数组的类型决定,比如int64占用8个字节等;

三、初始化数组方式:

package main

import "fmt"

func main() {
	// 初始化数组的方式
	// 第一种方式
	var numArr01 [3]int64 = [3]int64{1, 2, 3}
	fmt.Println("numArr01:", numArr01)
	// 第二种方式
	var numArr02 = [3]int64{4, 5, 6}
	fmt.Println("numArr02:", numArr02)
	// 第三种方式
	var numArr03 = [...]int64{7, 8, 9}
	fmt.Println("numArr03:", numArr03)
	// 第四种方式, 指定数组中下标的数值
	var numArr04 = [...]int64{1: 11, 0: 10, 2: 12}
	fmt.Println("numArr04:", numArr04)
	// 第五种方式, 类型推导
	strArr05 := [...]string{1: "_", 0: "fe", 2: "cow"}
	fmt.Println("strArr05:", strArr05)
}
                
 // 输出内容如下:
numArr01: [1 2 3]
numArr02: [4 5 6]
numArr03: [7 8 9]
numArr04: [10 11 12]
strArr05: [fe _ cow]

四、数组for-range 的使用:

基本语法

for index,value := range 数组 {

​ …

}

详细说明

  1. 第一个 index 是数组的下标;
  2. 第二个 value 是该下标位置的值;
  3. 它们仅在for 循环内部使用的局部变量;
  4. 遍历数组时,若不想使用下标或值,可使用_进行忽略;
  5. index、value 的命名不是固定的,通常起名为index、value

举个栗子

package main

import "fmt"

func main() {
	// 使用for-range 结构 遍历数组
	myArr := [...]string{"python", "java", "golang"}
	for index, value := range myArr{
		fmt.Printf("index=%v value=%v\n", index, value)
	}
	// 使用下划线, 进行忽略
	for _, v := range myArr{
		fmt.Printf("值为:%v\n", v)
	}
}
// 输出结果:
index=0 value=python
index=1 value=java
index=2 value=golang
值为:python
值为:java
值为:golang

五、数组注意事项与细节:

  1. 数组是多个相同类型数据的组合,一个数组声明(定义)了,长度是固定的,不能动态变化

    package main
    
    import (
    	"fmt"
    )
    func main() {
    	// 注意查看报错地方
    	var myArr [3]int
    	myArr[0] = 1
    	myArr[1] = 1.6   # 报错,因为myArr 定义的数据类型为int 而不是浮点型
    	myArr[2] = 2
    	myArr[3] = 3  # 报错,数据不能动态增长,因为myArr 数组长度为3,超出数组长度,不可动态生长
    	fmt.Println("myArr", myArr)
    }
    
  2. 数组中的元素可以是任意数据类型,包括值类型和引用类型,但是不能混用;

  3. 数组创建后,若没有赋值,有默认值(零值)

    package main
    
    import "fmt"
    
    func main() {
    	// 数组创建后, 没有赋值, 则使用的是数据类型的默认值
    	// int 类型的默认值:0
    	var intArr [3]int
    	// string 类型的默认值: ""
    	var strArr [3]string
    	// bool 类型的默认值: false
    	var boolArr [3]bool
    	fmt.Printf("int类型默认值:%v; string类型默认值:%v; bool类型的默认值:%v;",
    		intArr, strArr, boolArr)
    
    }
    // 输出结果:
    int类型默认值:[0 0 0]; string类型默认值:[  ]; bool类型的默认值:[false false false];
    
  4. 使用数组的步骤:

    a.声明数组时,此空间已被开辟;

    b.给数组每个元素赋值(默认零值);

    c.使用数组;

    package main
    
    import "fmt"
    
    func main() {
    	// 使用数组步骤
    	// 1.声明数组, 此时空间已经开辟
    	var myArr [3]int
    	// 2.给数组赋值
    	myArr[0] = 10
    	myArr[1] = 20
    	myArr[2] = 30
    	// 3.使用数组
    	for index, value := range myArr{
    		fmt.Printf("index=%v value=%v\n", index, value)
    	}
    }
    
  5. 数组的下标是从0开始

  6. 数组下标必须在指定范围内使用,否则报panic,数组越界

  7. go的数组属于值拷贝,在默认情况下是值传递,因此会进行值拷贝。数组间不会相互影响

    package main
    
    import "fmt"
    
    func test(arr [3]int) {
    	arr[0] = 100
    	fmt.Println("test函数栈, arr=", arr)
    }
    
    func main() {
    	// go 中,数组属于值拷贝,数组间并不会相互影响
    	myArr := [3]int{10, 20, 30}
    	test(myArr)
    	fmt.Println("main 函数栈, arr=", myArr)
    
    }
    // 输出结果:
    test函数栈, arr= [100 20 30]
    main 函数栈, arr= [10 20 30]
    

    流程图如下:
    Go 语言 数组的使用

  8. 若在其它函数中,修改原数组的值,可以使用引用传递(指针方式)

    package main
    
    import "fmt"
    
    func test(arr *[3]int) {
    	fmt.Printf("arr指针的地址是:%p\n", &arr)
    	(*arr)[0] = 666  // 注意 *arr 取到的就是myArr 数组; [0] 就是取到下标为0的空间
    }
    
    func main() {
    	// go 中 在其它函数中, 修改main函数中的数组的值
    	myArr := [3]int{11, 22, 33}
    	fmt.Printf("myArr数组的内存地址:%p\n", &myArr)
    	test(&myArr)
    	fmt.Println("main函数栈, myArr=", myArr)
    }
    //输出结果:
    myArr数组的内存地址:0xc00000e360
    arr指针的地址是:0xc000006030
    main函数栈, myArr= [666 22 33]
    

    流程图如下:
    Go 语言 数组的使用

  9. 长度是数组类型的一部分,在传递函数参数时,需要考虑数组长度,如下是错误示例:

    func test(arr []int) {
    	arr[0] = 100
    	fmt.Printf("test函数栈 arr=%v", arr)
    }
    
    func main() {
    	// 长度错误示例
    	var myArr = [...]int{11, 22 ,33}
    	test(myArr)
    }
    

    错误原因:不能把[3]int 传递给[ ]int;

    func test(arr [6]int) {
    	arr[0] = 100
    	fmt.Printf("test函数栈 arr=%v", arr)
    }
    
    func main() {
    	// 长度错误示例
    	var myArr = [...]int{11, 22 ,33}
    	test(myArr)
    }
    

    错误原因:不能把[3]int 传递给 [6]int;

相关标签: Go