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

【Go】--map和struct数据类型

Go 语言中的 map 和 struct 数据类型详解

map用于存储键值对,而struct用于组织不同类型的数据字段。

  • Map:适合处理动态的、无序的键值对数据
  • Struct:适合组织固定的、有结构的数据字段

1. Map(映射表)数据类型

1.1 基本概念

Map是一种无序的键值对集合,基于哈希表实现。

特性:

  • 键必须是可比较的类型(string、int等)
  • 值可以是任意类型
  • 无序存储,遍历顺序不确定

1.2 初始化方法

1.2.1 字面量初始化
// 整数键的map
mp1 := map[int]string{0: "a",1: "b", 2: "c",3: "d",4: "e",
}// 字符串键的map
mp2 := map[string]int{"a": 0,"b": 22,"c": 33,
}
1.2.2 使用make函数初始化
// 指定初始容量
mp1 := make(map[string]int, 8)
mp2 := make(map[string][]int, 10)

重要:

  • Map是引用类型,未初始化的map可以访问但无法存放元素
  • 必须为map分配内存后才能使用

1.3 访问操作

1.3.1 基本访问
mp := map[string]int{"a": 0,"b": 1,"c": 2,"d": 3,
}fmt.Println(mp["a"]) // 输出: 0
fmt.Println(mp["b"]) // 输出: 1
fmt.Println(mp["d"]) // 输出: 3
fmt.Println(mp["f"]) // 输出: 0 (不存在键返回零值)
1.3.2 存在性检查
if val, exist := mp["f"]; exist {fmt.Println(val)
} else {fmt.Println("key不存在")
}

1.4 存储操作

1.4.1 基本存储
mp := make(map[string]int, 10)
mp["a"] = 1
mp["b"] = 2
fmt.Println(mp) // 输出: map[a:1 b:2]
1.4.2 覆盖操作
mp := make(map[string]int, 10)
mp["a"] = 1
mp["b"] = 2if _, exist := mp["b"]; exist {mp["b"] = 3 // 覆盖原有值
}
fmt.Println(mp) // 输出: map[a:1 b:3]

1.5 特殊键值处理

1.5.1 NaN键的特殊情况
import "math"func main() {mp := make(map[float64]string, 10)mp[math.NaN()] = "a"mp[math.NaN()] = "b"mp[math.NaN()] = "c"_, exist := mp[math.NaN()]fmt.Println(exist) // 输出: falsefmt.Println(mp)    // 输出: map[NaN:c NaN:a NaN:b]
}

注意事项:

  • NaN作为键时会出现多个相同键的情况
  • 无法正常判断NaN键是否存在
  • 无法删除NaN键值对
  • 应避免使用NaN作为map的键

1.6 删除操作

func main() {mp := map[string]int{"a": 0,"b": 1,"c": 2,"d": 3,}fmt.Println(mp) // 输出: map[a:0 b:1 c:2 d:3]delete(mp, "a")fmt.Println(mp) // 输出: map[b:1 c:2 d:3]
}

1.7 遍历操作

func main() {mp := map[string]int{"a": 0,"b": 1,"c": 2,"d": 3,}for key, val := range mp {fmt.Println(key, val)}// 可能的输出(无序):// c 2// d 3// a 0// b 1
}

1.8 清空操作

1.8.1 Go 1.21之前的方法
func main() {m := map[string]int{"a": 1,"b": 2,}for k, _ := range m {delete(m, k)}fmt.Println(m) // 输出: map[]
}
1.8.2 Go 1.21及之后的方法
func main() {m := map[string]int{"a": 1,"b": 2,}clear(m)fmt.Println(m) // 输出: map[]
}

1.9 长度获取

func main() {mp := map[string]int{"a": 0,"b": 1,"c": 2,"d": 3,}fmt.Println(len(mp)) // 输出: 4
}

2. Struct(结构体)数据类型

2.1 基本概念

Struct是用于存储一组不同类型数据的复合类型。

特性:

  • 可以存储不同类型的数据字段
  • 通过组合实现类似继承的功能
  • 支持方法绑定

2.2 结构体声明

2.2.1 基本声明
type Programmer struct {Name     stringAge      intJob      stringLanguage []string
}type Person struct {name stringage  int
}
2.2.2 相邻字段简化声明
type Rectangle struct {height, width, area intcolor               string
}

命名规则:

  • 结构体本身及其字段都遵守大小写命名的暴露方式
  • 大写字母开头的字段可被外部包访问
  • 小写字母开头的字段只能在包内访问

2.3 实例化方法

2.3.1 字段名初始化(推荐)
programmer := Programmer{Name:     "jack",Age:      19,Job:      "coder",Language: []string{"Go", "C++"},
}
2.3.2 省略字段名初始化(不推荐)
programmer := Programmer{"jack",19,"coder",[]string{"Go", "C++"},
}

2.4 构造函数模式

2.4.1 基本构造函数
type Person struct {Name    stringAge     intAddress stringSalary  float64
}func NewPerson(name string, age int, address string, salary float64) *Person {return &Person{Name: name, Age: age, Address: address, Salary: salary}
}
2.4.2 选项模式(函数式选项模式)
type Person struct {Name     stringAge      intAddress  stringSalary   float64Birthday string
}// 选项函数类型
type PersonOptions func(p *Person)// 具体的选项函数
func WithName(name string) PersonOptions {return func(p *Person) {p.Name = name}
}func WithAge(age int) PersonOptions {return func(p *Person) {p.Age = age}
}func WithAddress(address string) PersonOptions {return func(p *Person) {p.Address = address}
}func WithSalary(salary float64) PersonOptions {return func(p *Person) {p.Salary = salary}
}// 构造函数
func NewPerson(options ...PersonOptions) *Person {p := &Person{}for _, option := range options {option(p)}// 默认值处理if p.Age < 0 {p.Age = 0}return p
}// 使用示例
func main() {p1 := NewPerson(WithName("John Doe"),WithAge(25),WithAddress("123 Main St"),WithSalary(10000.00),)p2 := NewPerson(WithName("Mike jane"),WithAge(30),)
}

2.5 组合(Composition)

2.5.1 显式组合
type Person struct {name stringage  int
}type Student struct {p      Personschool string
}type Employee struct {p   Personjob string
}// 使用示例
student := Student{p:      Person{name: "jack", age: 18},school: "lili school",
}
fmt.Println(student.p.name) // 输出: jack
2.5.2 匿名组合(类似继承)
type Person struct {name stringage  int
}type Student struct {Person  // 匿名组合school string
}type Employee struct {Person  // 匿名组合job string
}// 使用示例
student := Student{Person: Person{name: "jack", age: 18},school: "lili school",
}
fmt.Println(student.name) // 直接访问,输出: jack

2.6 指针操作

p := &Person{name: "jack"
}// 指针可以直接访问字段,无需解引用
fmt.Println(p.name) // 输出: jack

3. Map和Struct的对比

3.1 使用场景对比

特性MapStruct
数据结构键值对集合字段集合
键类型必须可比较固定字段名
顺序无序字段定义顺序固定
内存布局哈希表,动态连续内存,静态
性能O(1)访问O(1)字段访问
适用场景动态键值数据固定结构数据

3.2 性能考虑

  • Map:适合动态键值对,但哈希计算有开销
  • Struct:内存连续,访问速度快,但结构固定

4. 最佳实践

4.1 Map使用建议

  1. 预分配容量:使用make时指定合理容量减少扩容
  2. 存在性检查:访问前检查键是否存在
  3. 避免NaN键:避免使用math.NaN()作为键
  4. 并发安全:多goroutine访问时使用sync.Map

4.2 Struct使用建议

  1. 使用选项模式:复杂结构体使用函数式选项模式
  2. 合理使用组合:优先使用组合而非模拟继承
  3. 字段命名规范:遵循Go的命名约定
  4. 方法绑定:为结构体绑定相关方法

5. 实际应用示例

5.1 学生管理系统

type Student struct {ID      intName    stringGrades  map[string]float64Contact struct {Phone stringEmail string}
}func NewStudent(id int, name string) *Student {return &Student{ID:     id,Name:   name,Grades: make(map[string]float64),}
}// 使用示例
student := NewStudent(1, "Alice")
student.Grades["Math"] = 95.5
student.Grades["English"] = 88.0
student.Contact.Phone = "123-456-7890"
student.Contact.Email = "alice@example.com"

5.2 配置管理系统

type Config struct {Database struct {Host     stringPort     intUsername stringPassword string}Server struct {Port    intTimeout time.Duration}Features map[string]bool
}func LoadConfig() *Config {config := &Config{Features: make(map[string]bool),}// 加载配置逻辑...return config
}
http://www.dtcms.com/a/491079.html

相关文章:

  • go win安装grpc-gen-go插件
  • AI+Python驱动的无人机生态三维建模与碳储/生物量/LULC估算全流程实战技术
  • 网站管理助手 mysql小程序免费网站
  • 电商网站建设信息wordpress 中文转英文js
  • 【实战宝典】MySQL字符串包含查询大全:LIKE、REGEXP、全文索引深度剖析与实战代码
  • 手机网站推荐哪些学做莱网站
  • 建设网站的价格分析网站构架图
  • 后端八股之mysql
  • 力扣2563. 统计公平数对的数目
  • 在VMware上运行Linux(我选择的是Ubuntu)
  • 【Linux内核】Linux系统启动之旅
  • 正则表达式匹配不到表达式情况?
  • 【数据结构与算法_学习精华】
  • 第18讲:C语言内存函数
  • 外贸网站如何做推广论坛网站 备案
  • 深圳网站建设首选h5case是什么网站
  • Matlab的交通标志定位实现
  • 课堂网站开发企业管理培训班哪个好
  • 记录一个自动学习的脚本开发过程
  • h5游戏免费下载:一起蛙蛙跳
  • chrome中的axure插件提示无法不受支持
  • 石家庄住房城乡建设厅网站著名企业vi设计
  • 深圳做网站的公司排名开个人网站如何赚钱
  • centos 生产环境搭建最佳实践 (一)
  • RocketMQ 实战:马拉松系统异步化与延时任务落地(含死信队列处理)
  • 通达信指标平台
  • 网站建设及推广培训网站备案查询站长工具
  • MATLAB2025B版本新特点
  • Node.js使用Express+SQLite实现登录认证
  • 仿百度百科网站源码设计类专业学校有哪些