Go 语言 数组的使用

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; 

如图所示:
在这里插入图片描述
总结:

  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]
    

    流程图如下:
    在这里插入图片描述

  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]
    

    流程图如下:
    在这里插入图片描述

  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;

发布了158 篇原创文章 · 获赞 172 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/Fe_cow/article/details/104132891