当前位置: 首页 > news >正文

goland 语言--数组

一、数组的基本概念

数组是固定长度相同类型元素的有序集合

特点:

  • 长度固定:声明时必须指定长度,之后不能改变

  • 元素类型相同:所有元素必须是同一类型

  • 内存连续:元素在内存中是连续存储的

  • 零值初始化:声明后自动用零值初始化

  • 值类型:赋值或传参会复制整个数组

二、数组的声明和初始化

2.1 基本声明方式

package main import "fmt" func main() { // 方式1:声明后赋值(默认零值) var arr1 [5]int // 长度为5的int数组 fmt.Println("arr1:", arr1) // [0 0 0 0 0] // 方式2:声明并初始化 var arr2 [3]int = [3]int{1, 2, 3} fmt.Println("arr2:", arr2) // [1 2 3] // 方式3:使用短变量声明 arr3 := [4]string{"Go", "Java", "Python", "C++"} fmt.Println("arr3:", arr3) // [Go Java Python C++] // 方式4:让编译器计算长度 arr4 := [...]int{1, 2, 3, 4, 5, 6} fmt.Println("arr4:", arr4) // [1 2 3 4 5 6] fmt.Println("arr4长度:", len(arr4)) // 6 // 方式5:指定索引初始化 arr5 := [5]int{1: 20, 3: 40} fmt.Println("arr5:", arr5) // [0 20 0 40 0] // 方式6:部分初始化(其余为默认值) arr6 := [5]int{1, 2} fmt.Println("arr6:", arr6) // [1 2 0 0 0] }

2.2 不同类型数组示例

func arrayTypes() { // 整数数组 var intArr [3]int32 intArr[0] = 100 intArr[1] = 200 intArr[2] = 300 // 浮点数数组 floatArr := [3]float64{3.14, 2.71, 1.618} // 字符串数组 stringArr := [3]string{"Apple", "Banana", "Cherry"} // 布尔数组 boolArr := [3]bool{true, false, true} // 结构体数组 type Point struct { X, Y int } structArr := [2]Point{ {X: 1, Y: 2}, {X: 3, Y: 4}, } fmt.Printf("intArr: %v\n", intArr) fmt.Printf("floatArr: %v\n", floatArr) fmt.Printf("stringArr: %v\n", stringArr) fmt.Printf("boolArr: %v\n", boolArr) fmt.Printf("structArr: %v\n", structArr) }

三、数组的基本操作

3.1 访问和修改元素

func arrayOperations() { arr := [5]int{10, 20, 30, 40, 50} // 访问元素(索引从0开始) fmt.Println("第一个元素:", arr[0]) // 10 fmt.Println("第三个元素:", arr[2]) // 30 fmt.Println("最后一个元素:", arr[len(arr)-1]) // 50 // 修改元素 arr[1] = 99 fmt.Println("修改后:", arr) // [10 99 30 40 50] // 遍历数组 fmt.Println("\n=== 遍历数组 ===") // 方式1:for循环 for i := 0; i < len(arr); i++ { fmt.Printf("arr[%d] = %d\n", i, arr[i]) } // 方式2:for-range循环(推荐) for index, value := range arr { fmt.Printf("索引:%d, 值:%d\n", index, value) } // 方式3:只获取值 for _, value := range arr { fmt.Printf("值:%d ", value) } fmt.Println() // 方式4:只获取索引 for index := range arr { fmt.Printf("索引:%d ", index) } fmt.Println() }

3.2 数组的属性和方法

func arrayProperties() { arr := [5]int{1, 2, 3, 4, 5} // 获取长度 length := len(arr) fmt.Println("数组长度:", length) // 5 // 获取容量(数组的容量等于长度) capacity := cap(arr) fmt.Println("数组容量:", capacity) // 5 // 数组类型包含长度信息 fmt.Printf("数组类型: %T\n", arr) // [5]int }

四、多维数组

4.1 二维数组

func twoDimensionalArray() { // 声明二维数组 var matrix1 [3][3]int // 初始化二维数组 matrix2 := [3][3]int{ {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, } // 访问元素 fmt.Println("matrix2[1][2]:", matrix2[1][2]) // 6 // 修改元素 matrix2[0][0] = 100 // 遍历二维数组 fmt.Println("\n=== 遍历二维数组 ===") for i := 0; i < len(matrix2); i++ { for j := 0; j < len(matrix2[i]); j++ { fmt.Printf("%3d ", matrix2[i][j]) } fmt.Println() } // 使用for-range遍历 fmt.Println("\n=== for-range遍历 ===") for i, row := range matrix2 { for j, val := range row { fmt.Printf("matrix[%d][%d]=%d ", i, j, val) } fmt.Println() } }

4.2 更多维度的数组

func multiDimensionalArray() { // 三维数组 cube := [2][3][4]int{ { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, }, { {13, 14, 15, 16}, {17, 18, 19, 20}, {21, 22, 23, 24}, }, } fmt.Println("三维数组长度:") fmt.Println("第一维:", len(cube)) // 2 fmt.Println("第二维:", len(cube[0])) // 3 fmt.Println("第三维:", len(cube[0][0])) // 4 // 访问三维数组元素 fmt.Println("cube[1][2][3]:", cube[1][2][3]) // 24 }

五、数组的内存特性

5.1 数组是值类型

func arrayValueType() { // 数组是值类型,赋值会复制整个数组 arr1 := [3]int{1, 2, 3} arr2 := arr1 // 这里会发生数组的复制 fmt.Println("赋值前:") fmt.Println("arr1:", arr1) // [1 2 3] fmt.Println("arr2:", arr2) // [1 2 3] // 修改arr2不会影响arr1 arr2[0] = 100 fmt.Println("\n修改arr2后:") fmt.Println("arr1:", arr1) // [1 2 3] 不变! fmt.Println("arr2:", arr2) // [100 2 3] // 比较数组(只有相同长度和类型的数组才能比较) arr3 := [3]int{1, 2, 3} arr4 := [3]int{1, 2, 3} arr5 := [3]int{1, 2, 4} fmt.Println("\n数组比较:") fmt.Println("arr3 == arr4:", arr3 == arr4) // true fmt.Println("arr3 == arr5:", arr3 == arr5) // false fmt.Println("arr3 != arr5:", arr3 != arr5) // true }

5.2 数组作为函数参数

// 数组作为函数参数(值传递,会复制整个数组) func modifyArray(arr [5]int) { fmt.Println("函数内修改前:", arr) arr[0] = 999 fmt.Println("函数内修改后:", arr) } // 使用指针传递数组(避免复制) func modifyArrayByPointer(arr *[5]int) { fmt.Println("指针函数内修改前:", *arr) arr[0] = 888 // 可以直接使用arr[0],不需要(*arr)[0] fmt.Println("指针函数内修改后:", *arr) } func testArrayFunctions() { arr := [5]int{1, 2, 3, 4, 5} fmt.Println("原始数组:", arr) // 值传递 modifyArray(arr) fmt.Println("值传递后原数组:", arr) // 不变 // 指针传递 modifyArrayByPointer(&arr) fmt.Println("指针传递后原数组:", arr) // 改变 }

六、数组的实用技巧

6.1 数组切片操作

func arraySliceOperations() { arr := [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} // 将数组转换为切片(常用技巧) slice1 := arr[:] // 全部元素 slice2 := arr[3:] // 从索引3开始 slice3 := arr[:5] // 到索引5(不包括) slice4 := arr[2:7] // 从索引2到7 fmt.Println("原数组:", arr) fmt.Println("arr[:]:", slice1) // [0 1 2 3 4 5 6 7 8 9] fmt.Println("arr[3:]:", slice2) // [3 4 5 6 7 8 9] fmt.Println("arr[:5]:", slice3) // [0 1 2 3 4] fmt.Println("arr[2:7]:", slice4) // [2 3 4 5 6] // 修改切片会影响原数组 slice4[0] = 100 fmt.Println("\n修改切片后原数组:", arr) // arr[2]变为100 }

6.2 数组填充和复制

func arrayFillAndCopy() { // 使用循环填充数组 var squares [10]int for i := 0; i < len(squares); i++ { squares[i] = i * i } fmt.Println("平方数组:", squares) // 数组复制 source := [5]int{1, 2, 3, 4, 5} var dest [5]int // 方法1:直接赋值(复制整个数组) dest = source fmt.Println("复制后dest:", dest) // 方法2:使用copy函数(需要先转为切片) var dest2 [5]int copy(dest2[:], source[:]) fmt.Println("copy函数复制后dest2:", dest2) // 数组反转 reverseArr := [6]int{1, 2, 3, 4, 5, 6} for i, j := 0, len(reverseArr)-1; i < j; i, j = i+1, j-1 { reverseArr[i], reverseArr[j] = reverseArr[j], reverseArr[i] } fmt.Println("反转后数组:", reverseArr) }

七、数组的局限性和替代方案

7.1 数组的局限性

func arrayLimitations() { // 局限性1:长度固定,无法动态扩展 // arr := [3]int{1, 2, 3} // arr[3] = 4 // 编译错误:索引越界 // 局限性2:不同长度的数组是不同类型 arr1 := [3]int{1, 2, 3} arr2 := [4]int{1, 2, 3, 4} fmt.Printf("arr1类型: %T\n", arr1) // [3]int fmt.Printf("arr2类型: %T\n", arr2) // [4]int // 以下代码会编译错误 // arr1 = arr2 // 不能将[4]int赋值给[3]int // if arr1 == arr2 { } // 不能比较[3]int和[4]int }

7.2 数组 vs 切片

func arrayVsSlice() { fmt.Println("=== 数组 vs 切片 ===") // 数组:值类型,长度固定 array := [3]int{1, 2, 3} // 切片:引用类型,长度可变 slice := []int{1, 2, 3} fmt.Println("数组:", array, "类型:", reflect.TypeOf(array)) fmt.Println("切片:", slice, "类型:", reflect.TypeOf(slice)) // 修改测试 modifyArrayFunc := func(a [3]int, s []int) { a[0] = 100 s[0] = 100 } fmt.Println("\n调用函数前:") fmt.Println("array:", array) // [1 2 3] fmt.Println("slice:", slice) // [1 2 3] modifyArrayFunc(array, slice) fmt.Println("\n调用函数后:") fmt.Println("array:", array) // [1 2 3] 不变 fmt.Println("slice:", slice) // [100 2 3] 改变! }

八、总结要点

  1. 数组特性

    • 固定长度,声明时确定

    • 值类型,赋值会复制

    • 内存连续,访问速度快

  2. 使用场景

    • 数据长度固定且已知

    • 需要高性能访问

    • 栈空间分配(小数组)

    • 作为切片的基础存储

  3. 最佳实践

    • 小数组直接在栈上分配,性能好

    • 大数组考虑使用切片

    • 函数参数传递大数组时使用指针

    • 优先使用for-range遍历

  4. 常见错误

    • 访问越界(编译时检查)

    • 不同类型数组赋值

    • 忘记数组是值类型

------------------------------------------

数组常用的就是上面的了,还想再学点东西可以看看这个https://blog.csdn.net/dusk_star/article/details/155576705?fromshare=blogdetail&sharetype=blogdetail&sharerId=155576705&sharerefer=PC&sharesource=dusk_star&sharefrom=from_link

http://www.jsqmd.com/news/642804/

相关文章:

  • *8发散创新:基于Python的本体推理与知识表示实战应用**在人工智能和语义网
  • 数据分析方向毕业设计精选选题推荐【热门研究方向创新选题】2026
  • 优化IDEA堆内存配置以提升多线程应用性能
  • **刚体模拟的编程实践:用C++实现高效物理引擎中的碰撞检测与响应**在游戏开发、动画制作和
  • Qwen3-ASR-1.7B高精度ASR部署教程:对比0.6B版本,精度/显存/速度实测分析
  • node.js彩信接口如何集成?使用Node.js异步流模式发送多图片彩信
  • 配置node.js环境
  • SDMatte+模型详解:为何复杂边缘更准?权重结构与推理优化点解析
  • 避坑指南:在华为ENSP中配置多区域OSPF时,我踩过的那些‘坑’(含Stub区域、路由聚合、认证配置)
  • 放射科医生AI转型倒计时:2026奇点大会人才能力图谱发布——你的岗位未来18个月将被替代/增强/重构?立即测算你的不可替代指数
  • 投稿 IEEE Transactions overleaf 模板; Cover Letter模板;SCI论文投稿格式问题会直接拒稿吗; IEEE Transactions 投稿全流程状态
  • 从数据监测到训练优化:视觉训练 APP 的硬件联动逻辑
  • 【计组核心考点精讲】从模拟题看计算机组成原理期末复习策略
  • Go语言数组底层结构详解
  • 3D Face HRN实际案例:游戏建模师用单张照片批量生成角色面部UV贴图
  • qmc-decoder:快速解密QMC音频文件的终极免费工具
  • 【AHC】AHC 如何检测和回收空闲或失效的连接?健康检查机制是什么?
  • Git + 云原生:K8s配置版本化管理全攻略|GitOps实战与最佳实践
  • 反思学习!
  • IntelliJ IDEA 2026.1 全能配置指南:从零打造极致顺滑的 Java 开发环境
  • E7Helper:第七史诗自动化助手,如何实现24小时无忧挂机?
  • postman模拟post请求
  • 通义千问2.5-7B低成本上线:共享GPU资源部署案例
  • 《苍穹外卖》Spring版本不同,Spring3参数请求时需添加@ParameterObject,Swagger才能识别参数
  • 全球半导体全产业链展会哪家好?覆盖全链生态,甄选全球优质展会 - 品牌2026
  • 想做本地家政平台?这套 Java 源码帮你快速上线
  • 一文搞懂:TOP-K是撒网,Rerank是收网——RAG检索的“双重筛子”
  • 终极Alienware灯光风扇控制指南:用AlienFX Tools告别臃肿的AWCC
  • Phi-4-Reasoning-Vision快速上手:Streamlit分栏布局自定义配置
  • 开源TOP20项目(2026.04.01-2026.04.06)