news 2026/8/21 6:31:06

Go学习笔记:复杂数据类型——数组、切片、Map、结构体与指针

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Go学习笔记:复杂数据类型——数组、切片、Map、结构体与指针

📝本文首发于 栏轩·阁

欢迎访问阅读原文,获取更好的阅读体验。


一、数组(Array)— 定长

数组是固定长度的,一旦声明就不能改变长度。

// 声明:var 变量名 [长度]类型varnums[3]intnums[0]=10nums[1]=20nums[2]=30// 声明 + 初始化nums:=[3]int{10,20,30}// 让 Go 自己数长度nums:=[...]int{10,20,30}// 自动推断长度为 3// 数组长度是类型的一部分nums1:=[3]int{1,2,3}nums2:=[5]int{1,2,3,4,5}// nums1 = nums2 ← ❌ 编译错误!长度不同,类型不同

数组的局限:长度固定,不够灵活。实际开发中很少直接用数组,更常用的是切片。


二、切片(Slice)— 动态数组 ✅ 最常用

切片是 Go最常用的数据结构,类似于 Python 的 list 或 Java 的 ArrayList。

2.1 创建切片

// 方式1:字面量创建names:=[]string{"Go","Python","Rust"}// 方式2:make 创建nums:=make([]int,3)// [0, 0, 0],长度 = 3nums:=make([]int,3,5)// 长度 = 3,容量 = 5// 方式3:从数组切取arr:=[5]int{1,2,3,4,5}slice:=arr[1:4]// [2, 3, 4] 左闭右开

2.2 切片的增删改查

// 追加元素nums:=[]int{1,2,3}nums=append(nums,4)// [1, 2, 3, 4]nums=append(nums,5,6)// [1, 2, 3, 4, 5, 6]// 合并两个切片nums=append(nums,[]int{7,8}...)// ... 把切片展开// 获取长度和容量fmt.Println(len(nums))// 8,实际元素个数fmt.Println(cap(nums))// 底层数组容量(自动扩容)// 遍历fori,v:=rangenums{fmt.Printf("索引 %d = %d\n",i,v)}

2.3 长度 vs 容量

nums:=make([]int,3,5)// 长度 3,容量 5// nums = [0, 0, 0, _, _]// ↑ 长度 ↑ 容量(底层数组总大小)fmt.Println(len(nums))// 3fmt.Println(cap(nums))// 5nums=append(nums,1)// 还有容量,不会重新分配nums=append(nums,2)// [0, 0, 0, 1, 2]nums=append(nums,3)// 容量不够了 → 自动扩容为 2 倍

💡len表示能访问多少个元素,cap表示底层数组能放多少个。追加元素时,如果没超过 cap 就不会重新分配内存,效率更高。


三、Map — 键值对

类似于其他语言的字典 / HashMap。

// 创建 map// map[键类型]值类型scores:=make(map[string]int)scores["张三"]=90scores["李四"]=85// 创建 + 初始化scores:=map[string]int{"张三":90,"李四":85,"王五":92,}// 取值(安全方式:带 ok 判断是否存在)score,ok:=scores["赵六"]ifok{fmt.Println("分数:",score)}else{fmt.Println("此人不存在")}// 删除delete(scores,"李四")// 遍历(注意:map 遍历顺序不固定!)forname,score:=rangescores{fmt.Printf("%s: %d\n",name,score)}

⚠️ 遍历 Map 时顺序不固定,每次运行可能都不一样。如果需要固定顺序,先把 key 取出来排序再遍历。


四、结构体(struct)— 自定义类型

4.1 定义和使用

// 定义结构体typeUserstruct{NamestringAgeintEmailstring}// 使用u1:=User{"pc",25,"pc@example.com"}// 按字段顺序(不推荐)u2:=User{Name:"pc",Age:25,Email:"pc@example.com"}// 指定字段名(推荐 ✅)u3:=User{Name:"pc"}// 只赋值部分字段,其余为零值// 访问字段fmt.Println(u2.Name)// "pc"u2.Age=26// 修改字段

4.2 结构体方法

Go 没有 class,但可以给 struct 绑定方法:

typeUserstruct{NamestringAgeint}// 值接收者(不修改原始数据)func(u User)SayHello(){fmt.Printf("你好,我是 %s,今年 %d 岁\n",u.Name,u.Age)}// 指针接收者(可以修改原始数据)func(u*User)Birthday(){u.Age++}// 使用u:=User{Name:"pc",Age:25}u.SayHello()// 你好,我是 pc,今年 25 岁u.Birthday()// Age 变成 26u.SayHello()// 你好,我是 pc,今年 26 岁

💡什么时候用值接收者 vs 指针接收者?

  • 只读不修改 → 值接收者
  • 需要修改字段 → 指针接收者
  • 结构体很大 → 指针接收者(避免复制开销)

五、指针 — 简单理解

Go 的指针没有 C 的指针运算,比 C 安全得多。

// & 取地址 * 取值x:=10p:=&x// p 是一个指向 int 的指针fmt.Println(p)// 0xc0000...(内存地址)fmt.Println(*p)// 10(取指针指向的值)*p=20// 通过指针修改 xfmt.Println(x)// 20

为什么需要指针?

// 没有指针:值传递,原来的值不变funcdouble(xint){x=x*2}// 有指针:可以修改原来的值funcdouble(x*int){*x=*x*2}n:=5double(&n)fmt.Println(n)// 10

💡 新手阶段掌握&*就够了。在 Go 里,大部分时间用的是指针接收者(struct 方法)和切片(内部就是指针),不需要像 C 那样手动操作指针。


六、完整示例

typeStudentstruct{NamestringScorefloat64}func(s Student)Info()string{status:="不及格"ifs.Score>=60{status="及格"}returnfmt.Sprintf("%s: %.1f分 - %s",s.Name,s.Score,status)}funcmain(){// 用结构体 + 切片组织数据students:=[]Student{{"张三",85},{"李四",42},{"王五",93},}// 用 map 索引index:=make(map[string]float64)for_,s:=rangestudents{index[s.Name]=s.Score}// 查询for_,name:=range[]string{"张三","赵六"}{ifscore,ok:=index[name];ok{fmt.Printf("%s 的分数: %.1f\n",name,score)}else{fmt.Printf("%s 不存在\n",name)}}// 遍历for_,s:=rangestudents{fmt.Println(s.Info())}}

七、小结

类型特点常用程度
数组[n]T定长,用的少⭐⭐
切片[]T动态长度,最常用⭐⭐⭐⭐⭐
Mapmap[K]V键值对,快速查询⭐⭐⭐⭐
结构体struct组织多个字段,代替 class⭐⭐⭐⭐⭐
指针*T引用传值,注意 & 和 *⭐⭐⭐

下一课预告:错误处理与包管理——学会用好errorgo mod

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/21 6:30:00

模糊C均值聚类(FCM)原理详解与Python实现:从概念到图像分割实战

1. 从“非黑即白”到“亦此亦彼”:为什么我们需要模糊聚类 在数据分析、模式识别乃至我们日常的决策中,分类是一个永恒的主题。传统的聚类方法,比如K-Means,遵循一个非常“硬”的规则:一个数据点要么属于这个类&#x…

作者头像 李华
网站建设 2026/8/21 6:25:13

SpringBoot企业员工转正晋升系统开发实战

1. 项目概述:企业员工转正及晋升系统的核心价值这个基于SpringBoot的Java企业员工转正及晋升管理系统,本质上是一个高度专业化的人力资源考核平台。我在实际开发中发现,传统企业在这类流程管理上普遍存在三个痛点:纸质审批效率低下…

作者头像 李华
网站建设 2026/8/21 6:24:21

预警机时代的喜与忧:美军军事影像系统并非你想得那么好

在二十世纪九十年代的时候, 美军精确打击作战出现了重大变革, 美国空军的全时情报、监视、侦察也就是ISR成了联合作战的前提条件, 经过二十一世纪头十年的快速发展, 美国空军情报、监视、侦察能力持续提升, 满足了美军极大的作战需求, 全时情报、监视、侦察成了美国大兵在海外作…

作者头像 李华
网站建设 2026/8/21 6:24:19

蓝桥杯国赛题解析:用扩展欧拉定理破解指数塔取模难题

1. 项目概述:从一道国赛题看指数塔与数论的深度结合最近在复盘蓝桥杯国赛的历年真题,2023年那届的一道关于“2023次方的思考”的题目,给我留下了极深的印象。这道题远不止是简单的幂运算,它巧妙地将指数塔的计算与数论中的核心定理…

作者头像 李华