go语言结构体初始化 go语言结构体和复杂json

golang中级进阶(二):结构体目录
【go语言结构体初始化 go语言结构体和复杂json】一、结构体详解
1. 结构体定义
2. 实例化结构体的7种方法
二、结构体方法
1. 结构体的方法定义
2. 结构体内自定义方法的引用
3. 任意类型添加方法
三、嵌套、继承
1. 匿名结构体
2. 结构体中可以定义任意类型的字段
3. 结构体嵌套结构体
4. 结构体嵌套匿名结构体
5. 结构体嵌套多个匿名结构体
6. 结构体继承
四、结构体和JSON相互转换
1. 结构体转化成json
2. json转化成结构体
3. 结构体标签 tag
4. 嵌套结构体和json的序列化反序列化
Golang 中没有“类”的概念go语言结构体初始化,Golang 中的结构体和其他语言中的类有点相似 。和其他面向对 象语言中的类相比go语言结构体初始化,Golang 中的结构体具有更高的扩展性和灵活性 。
Golang 中的基础数据类型可以表示一些事物的基本属性,但是当我们想表达一个事物的全 部或部分属性时 , 这时候再用单一的基本数据类型就无法满足需求go语言结构体初始化了 , Golang 提供了一种 自定义数据类型,可以封装多个基本数据类型 , 这种数据类型叫结构体,英文名称 struct 。也就是我们可以通过 struct 来定义自己的类型了 。
使用 type 和 struct 关键字来定义结构体,具体代码格式如下:
type 类型名 struct {
字段名 字段类型
字段名 字段类型 …
}
其中:
? 类型名:表示自定义结构体的名称 , 在同一个包内不能重复 。
? 字段名:表示结构体字段名 。结构体中的字段名必须唯一 。
? 字段类型:表示结构体字段的具体类型 。
在 go 语言中 , 没有类的概念但是可以给类型(结构体,自定义类型)定义方法 。所谓方法 就是定义了接收者的函数 。接收者的概念就类似于其他语言中的 this 或者 self 。
方法的定义格式如下:
func (接收者变量 接收者类型) 方法名(参数列表) (返回参数) {
函数体
}
注意:想改变结构体内的值,必须先变成指针 。
在 Go 语言中,接收者的类型可以是任何类型,不仅仅是结构体,任何类型都可以拥有方法 。举个例子,我们基于内置的 int 类型使用 type 关键字可以定义新的自定义类型,然后为我们 的自定义类型添加方法 。
注意:匿名结构体中不允许出现多个重复的类型
注意:如果结构体里面有私有属性也就是小写定义的字段,则不会被json使用
golang 怎么判断一个结构体有没有被初始化过ect1 := new(Rect)
rect2 := Rect{}
rect3 := Rect{0, 0, 100, 200}
rect4 := Rect{width:100, height:200}
注意这几个变量全部为指向Rect结构go语言结构体初始化的指针(指针变量)go语言结构体初始化,因为使用了new()函数和操作符.而如果使用方法
a := Rect{}
则表示这个是一个Rect{}类型.两者是不一样go语言结构体初始化的.参考代码go语言结构体初始化:
func main() {
rect1 := Rect{0, 0, 100, 200}
rect1.x = 10
a := Rect{}
a.x = 15
fmt.Printf("%v\n%T\n", a, a)
fmt.Printf("%v\n%T\n", rect1, rect1)
}
运行结果为:
{15 0 0 0}
main.Rect
{10 0 100 200}
*main.Rect
Go语言中new和 make的区别详解new 主要用于结构体的初始化
make用于数组array,切片slice,协程chnnel的初始化
例如:users:=make([10]int);
msg:=make(chan int);
new会分配结构空间,并初始化为清空为零,不进一步初始化
new之后需要一个指针来指向这个结构
make会分配结构空间及其附属空间,并完成其间的指针初始化
make返回这个结构空间,不另外分配一个指针
例子new:
var p *[]int = new([]int)

p := new([]int)
以上分配了一个slice结构,但是结构中的应该指向底层数组的ptr指针为空 , 故实际不能往这个slice里面存取数据
同时分配了一个指针p,也即(在32位系统中)占4个字节并存放slice结构的地址
例子make:
var v []int = make([]int, 0)
v := make([]int, 0)
以上分配了一个slice结构,且结构中的应该指向底层数组的ptr指针已经指向了某个底层数组 , 这个底层数组应该已经分配了 , 故这个slice已经可以使用了
注意v就是这个slice结构,而不是一个指向slice的指针
上述仅是示例,一般使用时都会明确长度和容量:v := make([]int, 10, 50)
结论:
由上可见,用new来分配slice的意义不大,因为没有恰当的初始化,无法直接使用
有附带空间的结构,使用make来初始化 , 可以完成内部指针初始化 , 其后可以立即使用
讲讲go语言的结构体作为C语言家族的一员,go和c一样也支持结构体 。可以类比于java的一个POJO 。
在学习定义结构体之前,先学习下定义一个新类型 。
新类型 T1 是基于 Go 原生类型 int 定义的新自定义类型,而新类型 T2 则是 基于刚刚定义的类型 T1 , 定义的新类型 。
这里要引入一个底层类型的概念 。
如果一个新类型是基于某个 Go 原生类型定义的,那么我们就叫 Go 原生类型为新类型的底层类型
在上面的例子中,int就是T1的底层类型 。
但是T1不是T2的底层类型,只有原生类型才可以作为底层类型,所以T2的底层类型还是int
底层类型是很重要的,因为对两个变量进行显式的类型转换 , 只有底层类型相同的变量间才能相互转换 。底层类型是判断两个类型本质上是否相同的根本 。
这种类型定义方式通常用在 项目的渐进式重构 , 还有对已有包的二次封装方面
类型别名表示新类型和原类型完全等价,实际上就是同一种类型 。只不过名字不同而已 。
一般我们都是定义一个有名的结构体 。
字段名的大小写决定了字段是否包外可用 。只有大写的字段可以被包外引用 。
还有一个点提一下
如果换行来写
Age: 66,后面这个都好不能省略
还有一个点,观察e3的赋值
new返回的是一个指针 。然后指针可以直接点号赋值 。这说明go默认进行了取值操作
e3.Age等价于(*e3).Age
如上定义了一个空的结构体Empty 。打印了元素e的内存大小是0 。
有什么用呢?
基于空结构体类型内存零开销这样的特性,我们在日常 Go 开发中会经常使用空 结构体类型元素 , 作为一种“事件”信息进行 Goroutine 之间的通信
这种以空结构体为元素类建立的 channel,是目前能实现的、内存占用最小的 Goroutine 间通信方式 。
这种形式需要说的是几个语法糖 。
语法糖1:
对于结构体字段,可以省略字段名 , 只写结构体名 。默认字段名就是结构体名
这种方式称为 嵌入字段
语法糖2:
如果是以嵌入字段形式写的结构体
可以省略嵌入的Reader字段,而直接访问ReaderName
此时book是一个各个属性全是对应类型零值的一个实例 。不是nil 。这种情况在Go中称为零值可用 。不像java会导致npe
结构体定义时可以在字段后面追加标签说明 。
tag的格式为反单引号
tag的作用是可以使用[反射]来检视字段的标签信息 。
具体的作用还要看使用的场景 。
比如这里的tag是为了帮助encoding/json标准包在解析对象时可以利用的规则 。比如omitempty表示该字段没有值就不打印出来 。
golang 内置函数new 和struct 初始化的区别new()
这是一个用来分配内存go语言结构体初始化的内置函数go语言结构体初始化,它的第一个参数是一个类型,不是一个值,它的返回值是一个指向新分配的 t 类型的零值的指针 。
在golang的代码定义如下go语言结构体初始化:
func new(t Type) *Type
strut{}
直接使用struct{} 来初始化strut时,返回的是一个struct类型的值,而不是指针两者是不一样的
两者对比代码如下:
type Student struct{
id int
name string
}
func main(){
var s_1 *Student = new(Student)
s_1.id = 100
s_1.name = "cat"
var s_2 Student = Student{id:1,name:"tom"}
fmt.Println(s_1,s_2)
}
输出结果:
{100 cat} {1 tom}
从上面代码的声明和打印的结果中就可以看出 s_1 的类型为指针 , s_2 为一个Student类型
go 的选项模式现在有个结构体如下定义:
我们需要初始化结构体go语言结构体初始化,如果是其go语言结构体初始化他语言go语言结构体初始化,函数支持默认参数:
但是go语言结构体初始化,go语言函数不支持默认参数,同时即使go语言支持默认参数,但是如果配置项过多 , 那么每一个配置项都得写一个默认参数,也不现实 。
那么,在go语言中 , 我们怎么优雅的给其初始化呢 , 这时,就需要利用选项模式go语言结构体初始化了(option) 。
首先 , 我们定义一个option函数类型:
它接收一个参数: *Server。
然后定义一个 NewServer 函数,它接收一个 Option类型的不定参数:
最后 , 再直接定义一系列返回 Option的函数
使用时,直接:
go语言结构体初始化的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于go语言结构体和复杂json、go语言结构体初始化的信息别忘了在本站进行查找喔 。

    推荐阅读