Golang基础笔记五之结构体
本文首发于公众号:Hunter后端
原文链接:Golang基础笔记五之结构体
本篇笔记介绍 Golang 中的结构体。
在 Go 中,结构体是一种用户自定义的数据类型,可以将不同类型的数据组合在一起。
以下是本篇笔记目录:
- 结构体的定义和使用
- 嵌套结构体
- 创建结构体递归结构
- 结构体标签
1、结构体的定义和使用
结构体定义的基本语法如下:
type 结构体名称 struct{
field1 type
field2 type
}
我们可以先创建一个 struct:
type Person struct {
Name string
Age int
}
下面介绍几种方式来实例化结构体:
1. 使用结构体字面量初始化
使用结构体字面量初始化结构体变量,在创建结构体变量时,将字段值直接赋给结构体的字段。
其语法如下:
person := Person{Name: "Alice", Age: 30}
fmt.Println(person)
在这里,如果有字段没有赋值,那么这个字段的值就是该类型的零值。
2. 按字段顺序初始化
我们可以在初始化的时候不指定字段,那么它会按照结构体中的字段顺序进行赋值:
person := Person{"Alice", 30}
fmt.Println(person)
但是这个操作有个问题,就是结构体中的全部字段都需要赋值。
3. 使用 new 函数创建结构体指针
可以使用 new() 函数创建一个结构体,但是注意,其返回值是对应结构体的指针:
var person *Person = new(Person)
person.Age = 1
person.Name = "Hunter"
2、嵌套结构体
结构体可以嵌套在另一个结构体里,这个就是嵌套结构体。
1. 匿名嵌套
在嵌套的时候如果直接嵌套不指定字段名,这个就叫匿名嵌套,比如下面的示例:
type Address struct {
City string
}
type Person struct {
Name string
Age int
Address
}
这里没有给 Address 指定字段名,所以这个 Address 就是一个匿名字段。
以下是一个初始化的例子:
person := Person{
Name: "Hunter",
Age: 18,
Address: Address{
City: "Beijing",
},
}
使用匿名嵌套,我们可以直接访问到嵌套的结构体的字段:
fmt.Println(person.City)
这里 City 是 Addree 结构体的字段,但因为是匿名嵌套,所以可以直接访问到。
当然,也可以通过 Address 结构体进行访问:
fmt.Println(person.Address.City)
2. 具名嵌套
如果嵌套的时候显式指定字段名,就叫具名嵌套,比如:
type Company struct {
CompanyName string
}
type Person struct {
Name string
Age int
CompanyInfo Company
}
这里为了以示区分,给 Company 结构体的字段名设为 CompanyInfo,其初始化的方式还是类似的:
person := Person{
Name: "Hunter",
Age: 18,
CompanyInfo: Company{
CompanyName: "ACompany",
},
}
而如果要访问到嵌套的结构体的字段,则需要通过 CompanyInfo 进行访问:
fmt.Println(person.CompanyInfo.CompanyName)
3、创建结构体递归结构
我们可以通过结构体嵌套自己来形成递归结构,但是嵌套的类型需要是自身结构体的指针。
下面介绍一下使用结构体来创建链表和二叉树。
1. 链表
链表的结构体如下:
type ListNode struct {
Val int
Next *ListNode
}
接下来创建一个链表,并打印节点内容:
head := &ListNode{Val: 1}
node2 := &ListNode{Val: 2}
node3 := &ListNode{Val: 3}
head.Next = node2
node2.Next = node3
node := head
for {
if node == nil {
break
} else {
fmt.Println(node.Val)
node = node.Next
}
}
2. 二叉树
以下是二叉树的结构体:
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
接下来创建一个二叉树,并用前序遍历打印二叉树节点:
func preorderTraversal(root *TreeNode) {
if root == nil {
return
}
fmt.Println(root.Val)
if root.Left != nil {
preorderTraversal(root.Left)
}
if root.Right != nil {
preorderTraversal(root.Right)
}
}
root := &TreeNode{Val: 1}
root.Left = &TreeNode{Val: 2}
root.Right = &TreeNode{Val: 3}
root.Left.Left = &TreeNode{Val: 4}
root.Left.Right = &TreeNode{Val: 5}
preorderTraversal(root)
4、结构体标签
结构体标签是附加在结构体字段后的元数据字符串,可以用于 json 序列化和反序列化、Web 框架表单数据绑定、数据库 ORM 映射等。
下面介绍一下 json 标签的使用。
json 标签
json 标签用于 JSON 的序列化和反序列化,有以下几个功能:
- 字段映射:json:"field_name" 指定 JSON 字段名,如果不设置,默认为 struct 的字段名
- 忽略字段:json:"-" 表示该字段不参与序列化
- 忽略空值:json:"omitempty" 表示如果字段值为零值时,则不参与序列化
- 类型转换:json:"field_name,string", 表示将数值转换为字符串类型
下面是一个结构体示例:
type Person struct {
Name string `json:"name"`
Age int `json:"age,omitempty,string"`
Gender string `json:""`
Address string `json:"address"`
NoJsonField string `json:"-"`
}
在上面的结构体中,分别对字段实现了下面的操作:
- 将 Name 字段映射为 json 里的 name 字段
- Age 字段映射为 age 字段,如果 Age 字段值为零值,则不参与序列化,如果 Age 字段值不为零值,则将 Age 字段值转换为字符串类型
- Gender 字段映射到 json,但是不改变字段名
- Address 字段映射为 address 字段
- NoJsonField 字段不参与序列化
对于这些操作,我们使用下面的代码进行测试,记住,要先引入 json 模块:
import (
"encoding/json"
)
然后进行操作:
person := Person{
Name: "Hunter",
Age: 18,
Gender: "Male",
Address: "Beijing",
NoJsonField: "NoJsonValue",
}
_person, err := json.Marshal(person)
if err != nil {
fmt.Println("JSON 编码错误:", err)
} else {
fmt.Println(string(_person))
}
// 测试 omitempty,为零值时忽略
person.Age = 0
_person, err = json.Marshal(person)
if err != nil {
fmt.Println("JSON 编码错误:", err)
} else {
fmt.Println(string(_person))
}
分别打印出两条 json 数据:
{"name":"Hunter","age":"18","Gender":"Male","address":"Beijing"}
{"name":"Hunter","Gender":"Male","address":"Beijing"}
输出的结果可以印证前面我们对字段进行的定义逻辑。
除了 json 标签,还有 form 标签用于表单数据绑定,gorm 标签用于数据库映射,validate 标签用于数据验证等,后面有用到的时候再做介绍。
Golang基础笔记五之结构体的更多相关文章
- Golang基础(4):Go结构体
当我们要表示同一种数据类型时候,可以用到数组,切片和字典. 当我们要表示不同的数据类型呢?这时候就要用到结构体了 一:定义struct 关键字 type 和 struct 来定义结构体 type st ...
- Golang面向对象编程-struct(结构体)
Golang面向对象编程-struct(结构体) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是面向对象编程 面向对象编程(Object Oriented Program ...
- Golang Json文件解析为结构体工具-json2go
代码地址如下:http://www.demodashi.com/demo/14946.html 概述 json2go是一个基于Golang开发的轻量json文件解析.转换命令行工具,目前支持转换输出到 ...
- Go语言学习笔记十: 结构体
Go语言学习笔记十: 结构体 Go语言的结构体语法和C语言类似.而结构体这个概念就类似高级语言Java中的类. 结构体定义 结构体有两个关键字type和struct,中间夹着一个结构体名称.大括号里面 ...
- C#学习笔记05--枚举/结构体
一.枚举 当变量的取值范围是固定的几个时, 就可以使用枚举类型, 这样会更加简洁方便 1.1.定义: 访问修饰符 enum 枚举类型名 { 成员1, 成员2, 成员3, ... } publi ...
- matlab学习笔记12_3串联结构体,按属性创建含有元胞数组的结构体,filenames,isfield,isstruct,orderfields
一起来学matlab-matlab学习笔记12 12_3 结构体 串联结构体,按属性创建含有元胞数组的结构体,filenames,isfield,isstruct,orderfields 觉得有用的话 ...
- Golang通过反射拼接一个结构体所有字段
golang通过反射拼接一个结构体所有字段 需求 将一个结构体所有字段以"|"连接拼接成字符串 golang 不同类型拼接成string使用Sprintf比较麻烦,如果一个结构体有 ...
- GO语言系列(五)- 结构体和接口
结构体(Struct) Go中struct的特点 1. 用来自定义复杂数据结构 2. struct里面可以包含多个字段(属性) 3. struct类型可以定义方法,注意和函数的区分 4. struct ...
- Golang基础笔记
<基础> Go语言中的3个关键字用于标准的错误处理流程: defer,panic,recover. 定义一个名为f 的匿名函数: Go 不支持继承和重载. Go的goroutine概念:使 ...
- C#基础知识之类和结构体
虽然项目中一直在使用类.结构体等类型,仔细琢磨,还真无法系统的说出个所以然.记录一下类.结构体.类和结构体区别 一.类 对于类,大家都特别熟悉.简单的介绍一下类的结构,然后记录一下Class需要注意的 ...
随机推荐
- [源码系列:手写spring] IOC第十节:bean的初始化和销毁方法
内容介绍 在Spring框架中,你可以使用以下几种方法定义bean的初始化和销毁: 使用注解方式: @PostConstruct:在bean的方法上添加@PostConstruct注解,该方法将在be ...
- Code First 初始化数据时发生异常
问题重现 用Entity Framework的Code First默认生成的数据库文件被我直接删除了, 然后不管怎么重新编译等等, 运行后总是会报错如下: 解决方案同下 Cannot attach t ...
- JBoltAI Function Call技术解析:如何实现AI模型与企业系统的无缝对话
JBoltAI Function Call技术解析: 如何实现AI模型与企业系统的无缝对话 在企业级AI应用开发中,如何让大模型能力与现有系统高效协同一直是技术难点.JBoltAI框架通过Functi ...
- DeepseekScanner deepseek+python实现代码审计实战
一.功能概述 DeepseekScanner实现了扫描源代码项目中的所有代码文件发送给deepseek进行安全审计的功能.具体细节包括扫描所有子目录中的代码文件,然后依次将代码文件切片发送到deeps ...
- 一些CF上的补题0504
知识点模块 1.通过三点计算三角形的面积可以这样写 area=fabs(x1*y2-x2*y1+x2*y3-x3*y2+x3*y1-x1*y3)/2; 2.最小公倍数与最大公约数 x×y=gcd(x, ...
- 极客时间上新 .NET + AI 体系课
课程特色 1️⃣ 全网首个.NET+AI体系化课程(没有之一!) 2️⃣ Semantic Kernel + Kernel Memory 核心知识全覆盖 3️⃣ 每课时基于Polyglot Noteb ...
- Vue3+Ant-design项目启用ts/typescript
Ant-design官方文档提供了js和ts两种案例,按照文档给项目install ant-design后写了个组件编译时发现只要加上`<script lang="ts"&g ...
- JS 对象(Object)和字符串(String)互转方法、JS遍历对象
原文:https://www.cnblogs.com/fps2tao/p/8723164.html 1.对象(Object)和字符串(String)互转 利用原生JSON对象,将对象转为字符串 var ...
- 通过Linux包管理器提升权限
免责声明:本文所涉及的技术仅供学习和参考,严禁使用本文内容从事违法行为和未授权行为,如因个人原因造成不良后果,均由使用者本人负责,作者及本博客不承担任何责任. 前言 在Linux系统中,apt和yum ...
- Spring基于xml的CRUD
目录 基于xml的CRUD 代码实现 测试 基于xml的CRUD 源码 使用C3P0连接池 使用dbutils包中的QueryRunner类来对数据库进行操作 代码实现 pom.xml <?xm ...