go20/day02/array/README.md
yumaojun03 93e864c191 ```
feat(array): 添加数组遍历和排序功能及切片基础内容

添加了数组的range遍历方式详细说明,包括通用遍历法和专用遍历法的对比,
实现了冒泡排序函数MySort和指针版本MySortV2,完善了数组作为函数参数的
示例代码。同时新增了切片基础知识,包括slice结构定义、容量和长度概念,
以及切片与数组的区别说明。

chore: 初始化DevOps项目目录结构

创建了DevOps平台的整体目录框架,包含server、agent、web等子模块的
基础README文件,为后续DevOps功能开发奠定结构基础。
```
2026-01-11 14:55:03 +08:00

168 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 数组
![alt text](image.png)
[课件](https://gitee.com/infraboard/go-course/blob/master/zh-cn/base/array.md)
## 核心概念
根据容器里面数据类型不同,直接分配分配内存(连续的内存地址空间), 内存地址有开始和结束, 访问里面的对象, 我们需要传递索引, (这个索引会根据当前数据结构int8(一个字节) ADDRADDR(+1字节))
由于是连续内存地址, 访问速度极高
+ 长度固定
+ 类型一致(静态语言)
```go
# 数组表示
[]string{}, []int{}, []bool{},
# 特殊情况
[]any{}
```
## 定义数组
![alt text](image-1.png)
1. 数组声明 + 初始化
```go
// 声明数组: [长度]type
var arr [10]int64
// 这个数组的零值是 【0,0,0,0,0,0,0,0,0,0】
// 初始化数组
arr = [10]int64{1,2,3,4,5,6,7,8,9,10}
// 简短方式(声明 + 初始化)
// := 简单声明,
arr := [10]int64{1,2,3,4,5,6,7,8,9,10}
// 动态推算大小 ... => 10, 这种方式不怎么使用
arr := [...]int64{1,2,3,4,5,6,7,8,9,10}
```
2. 赋值: 基础类型的容器,表示多个
```go
// 找到元素(数组里面的插槽), 插槽编号 就是索引(0 - 结束)
arr[0] = 1
arr[1] = 2
arr[2] = 3
```
## 数组拷贝
go 默认就是值拷贝, = 赋值 也是 值copy
1. 浅拷贝: 创建一个新数组,新数组的元素和原数组的元素是相同的,但是两个数组的元素是两个不同的对象
```go
func main() {
// ipv4 4字节表示一个ipv4地址, 简短声明: 127.0.0.1
ip := [4]byte{127, 0, 0, 1}
fmt.Println("ip1:", ip)
// 如何copy这个数组, 这个赋值有没有完成copy
// 怎么理解数组的复制 是值拷贝
//
// a := 1
// b := a
// b = 2
// fmt.Println("a:", a)
// fmt.Println("b:", b)
// 数组: 一片连续的地址控制
// ip2 := ip ip 有自己连续的地址空间)
// ip2[4]byte{} (ip2 申请的连续地址)
// Go 默认是值拷贝(重要)
// ip 的值 传递给 ip2
// ip2 和 ip 是两个不同的数组, 互不影响
ip2 := ip
fmt.Println("ip2:", ip2)
// 修改ip2 不会影响ip
ip2[0] = 10
fmt.Println("ip1:", ip)
fmt.Println("ip2:", ip2)
}
```
## 数组遍历
1. 循环遍历(for)
```go
/*
数组遍历
*/
// 1. 通用遍历法(不局限于数组, 切片, map, 字符串)
// 对象的编号,通常叫索引, index (0, ...)
// (0, 1, 2, 3)
// 1. for : 定义变量(开始元素的索引0), 条件(循环结束条件, 不满足条件,结束循环), 变化(索引加1 找下一个元素)
// len 函数: 求数组的长度
// 127 0 0 1
// for i := 0; i < len(ip); i++ {
// fmt.Println(ip[i])
// }
// range 专用遍历法, 语法糖,更简洁, 自动处理索引的变化
// range len(ip) range 4
// range [0, 1, 2, 3]
// for i := range len(ip) {
// fmt.Println(ip[i])
// }
// 专门针对数组, 切片, map, 字符串的遍历
// 最常用的写法
// range array
// (index, value)
for i, v := range ip {
fmt.Println(i, v)
}
```
## 数组作为函数参数(比较少)
[3, 2, 5, 7] 进行排序,
```go
func MySort(arr [5]int) [5]int {
// 冒泡排序
for i := 0; i < len(arr)-1; i++ {
for j := 0; j < len(arr)-1-i; j++ {
if arr[j] > arr[j+1] {
// 值交换: a, b = b, a
arr[j], arr[j+1] = arr[j+1], arr[j]
}
}
}
return arr
}
func MySortV2(arr *[5]int) {
// 冒泡排序
for i := 0; i < len(arr)-1; i++ {
for j := 0; j < len(arr)-1-i; j++ {
if arr[j] > arr[j+1] {
// 值交换: a, b = b, a
arr[j], arr[j+1] = arr[j+1], arr[j]
}
}
}
}
```
## 作业
请同学们完成以下数组练习题以巩固对Go语言数组的理解
1. **定义和初始化数组**
定义一个包含5个整数的数组初始化为1到5并打印数组内容。
2. **数组遍历**
使用for循环遍历一个字符串数组打印每个元素的索引和值。
3. **数组拷贝**
创建一个数组,拷贝到另一个数组,修改原数组的第一个元素,观察拷贝后的数组是否改变。
4. **数组作为函数参数**
编写一个函数,接受一个整数数组作为参数,计算并返回数组中所有元素的和。
请将代码写在 `main.go` 文件中,并运行测试。