Go语言数组

一、数组

1. 基本介绍

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

想象一下,数组就像一个固定大小的储物柜,有着明确数量的格子,每个格子只能存放相同类型的物品。一旦这个储物柜建好了,格子的数量就不能改变了。

2. 如何定义数组

复制代码
var 数组名 [数组大小]数据类型

例如:

复制代码
var arr [3]int

在Go语言中,定义数组有多种方式:

复制代码
// 1. 最基础的定义方式
var scores [3]int  // 定义一个能存放3个整数的数组

// 2. 定义时直接赋值
var prices = [3]float64{10.99, 20.99, 30.99}

// 3. 让编译器自动计算长度
names := [...]string{"张三", "李四", "王五"}

// 4. 指定特定位置的值
colors := [5]string{0: "红", 2: "蓝", 4: "绿"}  // [红 "" 蓝 "" 绿]
2.1. 初始化数组
2.1.1. 普通初始化-声明并初始化
复制代码
//(1)普通初始化
    var arr01 [3]int=[3]int{1,2,3}
    fmt.Println("arr01=",arr01)
2.1.2. 省略声明类型-类型推断初始化
复制代码
//(2)省略声明类型
    var arr02 = [3]int{4,5,7}
    fmt.Println("arr02=",arr02)
2.1.3. [...]不指定数组元素个数-让编译器推断长度
复制代码
frameworks := [...]string{"Gin", "Echo", "Fiber", "Beego"}
fmt.Printf("Go Web框架: %v (长度: %d)\n", frameworks, len(frameworks))
2.1.4. 指定位置初始化-指定索引初始化
复制代码
//(4)指定位置初始化,按数组下标来指定初始化,没被初始化的默认为0
weekdays := [7]string{0: "周一", 1: "周二", 6: "周日"}
fmt.Printf("工作日安排: %v\n", weekdays)
2.1.5. 零值初始化
复制代码
var userLevels [10]int
fmt.Printf("userLevels: %v\n", userLevels)

3. 数组的特点

  1. 长度固定:一旦定义,长度不可改变
  2. 类型固定:同一个数组只能存储相同类型的元素
  3. 长度是类型的一部分:[3]int[5]int是不同的类型

示例:

复制代码
func SliceDemo1() {
	var scores [5]int = [5]int{95, 89, 92, 88, 96}
	sum := 0
	for _, value := range scores {
		sum += value
	}
	fmt.Println(sum)
	average := float64(sum) / float64(len(scores))
	fmt.Printf("平均分:%.2f\n", average)
}

输出:

460

平均分:92.0

4. 数组的使用

4.1. 数组的遍历
    1. 方式一:常规遍历

    var arr = [...]int{1, 4, 6, 7, 8}
    //遍历数组
    for i := 0; i < len(arr); i++ {
    fmt.Println(arr[i])
    }

    1. 方式二:for-range 结构遍历

基本语法:

复制代码
for index,value:=range arr{
...
}

说明:

    • 第一个返回值 index 是数组的下标
    • 第二个 value 是 index 下标对应的值
    • index 和 value 是在 for 循环内部的局部变量
    • 遍历数组元素的时候,若不想用下标 index,可以直接把下标 index 标位下划线_
    • index 和 value 的名称是用户自定义的,一般命名为 index 和 value

案例

复制代码
var arr = [...]int{1, 4, 6, 7, 8}
for _, value := range arr {
		fmt.Println(value)
	}
4.2. 数组使用细节
  • 数组是多个相同类型数据的组合,一个数组一旦声明/定义了,其长度是 固定的 ,不能动态变化
  • var arr [] int 这时 arr 就是一个 slice 切片
  • 数组中的元素可以是任何数据,包括值类型和引用类型,但是不能混用
  • 数组的下标是从 0 开始的, 下标必须在指定范围内使用,否则 panic:数组越界
  • 数组创建后,若没有赋值,有默认值, 数值 类型默认为 0 字符串 类型默认为 "" bool 类型默认为 false
  • Go 的数组属于值类型,在默认情况下是 值传递 ,因此会进行值拷贝,数组间不会相互影响
  • 长度是数组类型的一部分,在传递函数参数时,需要考虑数组的长度
4.3. 实际应用
4.3.1. 一维数组的应用,简单模版:
复制代码
func TemplateManager() {
	//类别管理
	var templateCategories [6]string
	templateCategories[0] = "Go"
	templateCategories[1] = "Java"
	templateCategories[2] = "Python"
	templateCategories[3] = "C#"
	templateCategories[4] = "Ruby"
	templateCategories[5] = "PHP"
	fmt.Println("=== 模板分类 ===")
	for index, value := range templateCategories {
		fmt.Printf("%d. %s\n", index+1, value)
	}
	// 每个分类的模板数量统计
	templateCounts := [6]int{25, 18, 12, 15, 10, 8}
	fmt.Println("\n=== 各分类模板数量 ===")
	templateTotal := 0
	for i, count := range templateCounts {
		fmt.Printf("%s. %d个模版\n", templateCategories[i], count)
		templateTotal += count
	}
	fmt.Printf("总计: %d个模板\n", templateTotal)
	// 找出最受欢迎的分类
	maxCount := 0
	popularCategory := ""
	for index, value := range templateCounts {
		if value > maxCount {
			maxCount = value
			popularCategory = templateCategories[index]
		}
	}
	fmt.Printf("最受欢迎的分类: %s (%d个模板)\n", popularCategory, maxCount)
}

输出:

=== 模板分类 ===

  1. Go

  2. Java

  3. Python

  4. C#

  5. Ruby

  6. PHP

=== 各分类模板数量 ===

Go. 25个模版

Java. 18个模版

Python. 12个模版

C#. 15个模版

Ruby. 10个模版

PHP. 8个模版

总计: 88个模板

最受欢迎的分类: Go (25个模板)

4.3.2. 二维数组

多维数组就像‌一个立体的储物系统,比⁢如一个有多层多排的⁡书架。在实际开发中,多维数؜组常用于表示表格、矩阵‎、游戏地图等二维或多维数据。

示例:

复制代码
func SliceDemo4() {
	// 行代表知识点,列代表难度等级(简单、中等、困难)
	questionMatrix := [4][3]int{
		{15, 8, 3},  // 数据结构题目数量
		{12, 10, 5}, // 算法题目数量
		{20, 6, 2},  // 基础语法题目数量
		{8, 12, 8},  // 系统设计题目数量
	}
	categories := [4]string{"数据结构", "算法设计", "基础语法", "系统设计"}
	difficulties := [3]string{"简单", "中等", "困难"}
	fmt.Println("=== 题库分布统计 ===")
	fmt.Printf("%-12s", "知识点\\难度")
	for _, value := range difficulties {
		//输出难度
		fmt.Printf("%-8s", value)
	}
	fmt.Println("总计")
	//知识点总数
	totalByCategory := [4]int{}
	//难度总数
	totalByDifficulty := [3]int{}
	grandTotal := 0

	//遍历知识点
	for i, category := range categories {
		fmt.Printf("%-12s", category)
		categoryTotal := 0
		//根据知识点获取难度列表的数量
		for j, count := range questionMatrix[i] {
			fmt.Printf("%-8d", count)
			//知识点总数
			categoryTotal += count
			//难度总数
			totalByDifficulty[j] += count
			grandTotal += count
		}
		totalByCategory[i] = categoryTotal
		fmt.Printf("%d\n", categoryTotal)
	}
	// 打印统计行
	fmt.Printf("%-12s", "总计")
	for _, value := range totalByDifficulty {
		fmt.Printf("%-8d", value)
	}
	//打印总计数量
	fmt.Printf("%-12d\n", grandTotal)

	// 分析数据
	fmt.Println("\n=== 数据分析 ===")
	fmt.Println(totalByCategory[0])
	maxCategoryIndex := 0
	for index, total := range totalByCategory {
		if total > totalByCategory[maxCategoryIndex] {
			maxCategoryIndex = index
		}
	}
	fmt.Printf("题目最多的分类: %s (%d题)\n",
		categories[maxCategoryIndex], totalByCategory[maxCategoryIndex])

	fmt.Printf("简单题占比: %.1f%%\n",
		float64(totalByDifficulty[0])/float64(grandTotal)*100)
}

输出:

=== 题库分布统计 ===

知识点\难度 简单 中等 困难 总计

数据结构 15 8 3 26

算法设计 12 10 5 27

基础语法 20 6 2 28

系统设计 8 12 8 28

总计 55 36 18 109

=== 数据分析 ===

26

题目最多的分类: 基础语法 (28题)

简单题占比: 50.5%

4.3.3. 三维数组

示例:

复制代码
func SliceDemo5() {
	// 编程导航学习进度追踪
	// 维度:[用户][课程][周数] = 学习时长(小时)
	studyProgress := [3][4][4]int{
		{ // 用户1: 张三
			{2, 3, 4, 5}, // Go基础课程,4周学习时长
			{1, 2, 3, 4}, // 算法课程
			{0, 1, 2, 3}, // 项目实战
			{0, 0, 1, 2}, // 面试准备
		},
		{ // 用户2: 李四
			{3, 4, 5, 6}, // Go基础课程
			{2, 3, 4, 5}, // 算法课程
			{1, 2, 3, 4}, // 项目实战
			{1, 1, 2, 3}, // 面试准备
		},
		{ // 用户3: 程序员鱼皮
			{5, 6, 7, 8}, // Go基础课程
			{4, 5, 6, 7}, // 算法课程
			{3, 4, 5, 6}, // 项目实战
			{2, 3, 4, 5}, // 面试准备
		},
	}
	users := [3]string{"张三", "李四", "Linruxin"}
	courses := [4]string{"Go基础", "算法课程", "项目实战", "面试准备"}

	fmt.Println("=== 编程导航学习进度报告 ===")
	for userIndex, user := range users {
		fmt.Printf("\n%s 的学习情况:\n", user)
		userTotal := 0
		for courseIndex, course := range courses {
			fmt.Printf("  %s: ", course)
			courseTotal := 0
			for week := 0; week < 4; week++ {
				hours := studyProgress[userIndex][courseIndex][week]
				fmt.Printf("第%d周(%d小时) ", week+1, hours)
				courseTotal += hours
				userTotal += hours
			}
			fmt.Printf("- 小计: %d小时\n", courseTotal)
		}
		fmt.Printf("  总学习时长: %d小时\n", userTotal)
	}
}

输出:

=== 编程导航学习进度报告 ===

张三 的学习情况:

Go基础: 第1周(2小时) 第2周(3小时) 第3周(4小时) 第4周(5小时) - 小计: 14小时

算法课程: 第1周(1小时) 第2周(2小时) 第3周(3小时) 第4周(4小时) - 小计: 10小时

项目实战: 第1周(0小时) 第2周(1小时) 第3周(2小时) 第4周(3小时) - 小计: 6小时

面试准备: 第1周(0小时) 第2周(0小时) 第3周(1小时) 第4周(2小时) - 小计: 3小时

总学习时长: 33小时

李四 的学习情况:

Go基础: 第1周(3小时) 第2周(4小时) 第3周(5小时) 第4周(6小时) - 小计: 18小时

算法课程: 第1周(2小时) 第2周(3小时) 第3周(4小时) 第4周(5小时) - 小计: 14小时

项目实战: 第1周(1小时) 第2周(2小时) 第3周(3小时) 第4周(4小时) - 小计: 10小时

面试准备: 第1周(1小时) 第2周(1小时) 第3周(2小时) 第4周(3小时) - 小计: 7小时

总学习时长: 49小时

Linruxin 的学习情况:

Go基础: 第1周(5小时) 第2周(6小时) 第3周(7小时) 第4周(8小时) - 小计: 26小时

算法课程: 第1周(4小时) 第2周(5小时) 第3周(6小时) 第4周(7小时) - 小计: 22小时

项目实战: 第1周(3小时) 第2周(4小时) 第3周(5小时) 第4周(6小时) - 小计: 18小时

面试准备: 第1周(2小时) 第2周(3小时) 第3周(4小时) 第4周(5小时) - 小计: 14小时

总学习时长: 80小时

相关推荐
白宇横流学长2 小时前
基于SpringBoot实现的零食销售商城设计与实现【源码+文档】
java·spring boot·后端
qq_336313932 小时前
Java基础-Stream流
java·开发语言·windows
superman超哥2 小时前
仓颉语言中异常捕获机制的深度剖析与工程实践
c语言·开发语言·后端·python·仓颉
再__努力1点2 小时前
【76】Haar特征的Adaboost级联人脸检测全解析及python实现
开发语言·图像处理·人工智能·python·算法·计算机视觉·人脸检测
驱动探索者2 小时前
[缩略语大全]之[INTEL]篇
java·后端·spring·intel
one9962 小时前
C# 的进程间通信(IPC,Inter-Process Communication)
开发语言·c#
Victor3562 小时前
Netty(21)Netty的SSL/TLS支持是如何实现的?
后端
IT_陈寒2 小时前
Java21新特性实战:5个杀手级改进让你的开发效率提升40%
前端·人工智能·后端
跟着珅聪学java2 小时前
以下是使用JavaScript动态拼接数组内容到HTML的多种方法及示例:
开发语言·前端·javascript