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

Go初级之五:结构体与方法

Go初级之五:结构体与方法

在Go语言中,结构体(struct)方法(method) 是实现面向对象编程的核心机制。虽然Go不是传统意义上的面向对象语言(没有类、继承等概念),但通过结构体和方法的组合,可以非常优雅地组织代码。


一、结构体(Struct)

1. 什么是结构体?

结构体是一种自定义的数据类型,用于将多个不同类型的数据字段组合在一起,形成一个有意义的整体。

类比:就像“学生”这个概念,包含姓名、年龄、成绩等多个属性。

2. 定义结构体

type Student struct {Name  stringAge   intScore float64
}
  • type:关键字,用于定义新类型。
  • Student:结构体名称(大写表示对外可见)。
  • {} 内是字段列表,每个字段有名字和类型。

3. 创建结构体实例

方式一:使用 struct{} 字面量
s1 := Student{Name: "张三",Age: 18,Score: 95.5,
}
方式二:按顺序赋值(不推荐,易错)
s2 := Student{"李四", 17, 88.0}
方式三:new 创建指针
s3 := new(Student)
s3.Name = "王五"
s3.Age = 19
s3.Score = 90.0
// 等价于 s3 := &Student{}

4. 访问结构体字段

fmt.Println(s1.Name)   // 输出:张三
fmt.Println(s1.Age)    // 输出:18
s1.Score = 96.0        // 修改字段

二、方法(Method)

1. 什么是方法?

方法是绑定到某个类型上的函数。在Go中,你可以为结构体(甚至基本类型)定义方法。

2. 定义方法

语法:

func (接收者 变量名 类型) 方法名(参数列表) 返回值 {// 方法体
}
示例:为 Student 定义一个方法
func (s Student) PrintInfo() {fmt.Printf("姓名: %s, 年龄: %d, 成绩: %.2f\n", s.Name, s.Age, s.Score)
}func (s Student) IsPass() bool {return s.Score >= 60
}
调用方法:
s := Student{"张三", 18, 95.5}
s.PrintInfo()  // 姓名: 张三, 年龄: 18, 成绩: 95.50
fmt.Println(s.IsPass()) // true

3. 值接收者 vs 指针接收者

❌ 值接收者(不会修改原结构体)
func (s Student) SetName(name string) {s.Name = name // 只修改副本
}

调用后原结构体不变。

✅ 指针接收者(可以修改原结构体)
func (s *Student) SetName(name string) {s.Name = name // 修改原始结构体
}

调用:

s := Student{"张三", 18, 95.5}
s.SetName("李四")
fmt.Println(s.Name) // 输出:李四

建议:如果方法需要修改结构体,或结构体较大(避免复制开销),使用指针接收者。


三、结构体的高级用法

1. 匿名字段(模拟“继承”)

Go没有继承,但可以通过匿名字段实现类似效果。

type Person struct {Name stringAge  int
}type Student struct {Person  // 匿名字段Score   float64School  string
}

使用:

s := Student{Person: Person{Name: "张三", Age: 18},Score:  95.5,School: "清华",
}fmt.Println(s.Name)  // 直接访问匿名字段的属性
fmt.Println(s.Age)
fmt.Println(s.Score)

这叫“组合”,不是继承,是Go推崇的设计模式。


2. 结构体标签(Struct Tag)——常用于JSON序列化

type User struct {ID   int    `json:"id"`Name string `json:"name"`Age  int    `json:"age"`
}

使用 json.Marshal

u := User{ID: 1, Name: "Alice", Age: 25}
data, _ := json.Marshal(u)
fmt.Println(string(data)) 
// 输出:{"id":1,"name":"Alice","age":25}

常见用途:JSON、数据库ORM(如GORM)、表单验证等。


四、完整示例:学生管理系统

package mainimport "fmt"// 1. 定义结构体
type Student struct {Name  stringAge   intScore float64
}// 2. 定义方法
func (s Student) Print() {fmt.Printf("学生: %s, 年龄: %d, 成绩: %.2f\n", s.Name, s.Age, s.Score)
}func (s *Student) Promote() {s.Age++fmt.Printf("%s 升了一岁,现在 %d 岁\n", s.Name, s.Age)
}func (s Student) IsExcellent() bool {return s.Score >= 90
}// 3. 主函数
func main() {s := Student{"张三", 18, 95.5}s.Print()           // 学生: 张三, 年龄: 18, 成绩: 95.50fmt.Println(s.IsExcellent()) // trues.Promote()         // 张三 升了一岁,现在 19 岁
}

五、最佳实践与注意事项

项目建议
结构体名驼峰命名,首字母大写表示导出
字段名同上,小写为包内私有
方法接收者小结构用值接收者,大结构或需修改时用指针
组合代替继承多用匿名字段组合,少用嵌套
使用TagJSON、数据库操作时务必使用

六、常见面试题

  1. 值接收者和指针接收者的区别?

    • 值接收者:操作副本,不改变原值。
    • 指针接收者:操作原值,可修改。
  2. Go有继承吗?

    • 没有,但可以通过匿名字段实现组合。
  3. 什么时候用指针接收者?

    • 方法会修改结构体。
    • 结构体较大(避免复制开销)。
    • 保持一致性(同一个类型的方法尽量统一用指针或值)。

✅ 总结

概念说明
struct自定义复合数据类型
method绑定到类型的函数
接收者(s Type)(s *Type)
匿名字段实现组合,“has-a”关系
Struct Tag元信息,用于JSON、ORM等

下一节预告:Go初级之六:接口(Interface)—— 实现多态与解耦

http://www.dtcms.com/a/356673.html

相关文章:

  • 二手奢侈品拍照估价上门快递回收小程序开发
  • 前端如何使用canvas实现截图
  • 【前端教程】从零开始学JavaScript交互:7个经典事件处理案例解析
  • 嵌入式Linux驱动开发 - DTS LED驱动
  • 拼多多商品信息批量获取及开放API接口调用指南
  • 【面试场景题】dubbo可以使用自定义的序列化协议吗
  • 音视频学习(五十九):H264中的SPS
  • Kubernetes: 解构Karpenter NodePool, 云原生时代的弹性节点管理艺术
  • 【K8s】整体认识K8s之集群的pod之间的通信
  • LSM6DS3姿态芯片和LIS2MD磁力计芯片数据读取(stm32)
  • 千年智造,一触即发 耐达讯自动化Profibus集线器如何让HMI触摸屏在工业4.0中“点石成金“?
  • 嵌入式Linux驱动开发 - 并发控制机制
  • 【视频讲解】R语言海七鳃鳗性别比分析:JAGS贝叶斯分层逻辑回归MCMC采样模型应用
  • 嵌入式Linux驱动开发 - 新字符设备LED驱动
  • Go Vendor 和 Go Modules:管理和扩展依赖的最佳实践
  • Redis vs Elasticsearch:核心区别深度解析
  • Vue 项目首屏加载速度优化
  • Mysql系列--11、使用c/c++访问mysql服务
  • ViennaCL并行异构库介绍和使用
  • Pinterest自动化 “Pin“得高效
  • SpringMvc下
  • Oracle SQL 性能调优的基石:深入解读与驾驭执行计划
  • 商家协同生态下的复购革命:跨店收益如何激活12%增量消费
  • 【新启航】3D 逆向抄数的工具技术与核心能力:基于点云处理的扫描设备操作及模型重建方法论
  • 【活动回顾】“智驱未来,智领安全” AI+汽车质量与安全论坛
  • OpenEuler部署LoganaLyzer
  • 【开题答辩全过程】以 基于SpringBootVue的智能敬老院管理系统为例,包含答辩的问题和答案
  • 黑芝麻智能与云深处科技达成战略合作,共推具身智能平台全球市场应用
  • 基于互补素数与最小素因子性质的哥德巴赫猜想证明-陈墨仙
  • ROS2学习打卡表