相同点:都是给变量分配内存
不同点:
作用:defer延迟函数,释放资源,收尾工作;如释放锁,关闭文件,关闭链接;捕获panic;
避坑指南:defer函数紧跟在资源打开后面,否则defer可能得不到执行,导致内存泄露。
执行顺序:多个 defer 调用顺序是 LIFO(后入先出),defer后的操作可以理解为压入栈中
defer,return,return value(函数返回值) 执行顺序:先进行返回值赋值,再执行 defer,最后执行 return 指令。defer可以修改函数最终返回值,修改时机:有名返回值或者函数返回指针
每个 defer 语句都对应一个_defer 实例,多个实例使用指针连接起来形成一个单连表,保存在 gotoutine 数据结构中,每次插入_defer 实例,均插入到链表的头部,函数结束再一次从头部取出,从而形成后进先出的效果。
defer 的规则总结:
在 for a,b := range c 遍历中, a 和 b 在内存中只会存在一份,即之后每次循环时遍历到的数据都是以值覆盖的方式赋给 a 和 b,a,b 的内存地址始终不变。由于有这个特性,for 循环里面如果开协程,不要直接把 a 或者 b 的地址传给协程。解决办法:在每次循环时,创建一个临时变量。
如果超过这些最大值最小值,会“回绕”并从 0 或最大值(依据操作系统)继续计数
Go 中解析的 tag 是通过反射实现的,反射是指计算机程序在运行时(Run time)可以访问、检测和修改它本身状态或行为的一种能力或动态知道给定数据对象的类型和结构,并有机会修改它。反射将接口变量转换成反射对象 Type 和 Value;反射可以通过反射对象 Value 还原成原先的接口变量;反射可以用来修改一个变量的值,前提是这个值可以被修改;tag是啥:结构体支持标记,name string json:name-field
就是 json:name-field
这部分
go 的 select 为 golang 提供了 IO 多路复用机制,用于检测是否有读写事件是否 ready。linux 的系统 IO 模型有 select,poll,epoll,go 的 select 和 linux 系统 select 非常相似。
select 结构组成主要是由 case 语句和执行的函数组成 select 实现的多路复用是:每个线程或者进程都先到注册和接受的 channel(装置)注册,然后阻塞,然后只有一个线程在运输,当注册的线程和进程准备好数据后,装置会根据注册的信息得到相应的数据。
select 的特性
Go 的 Context 的数据结构包含 Deadline,Done,Err,Value,Deadline 方法返回一个time.Time,表示当前 Context 应该结束的时间,ok 则表示有结束时间,Done 方法当 Context 被取消或者超时时候返回的一个 close 的 channel,告诉给 context 相关的函数要停止当前工作然后返回了,Err 表示 context 被取消的原因,Value 方法表示 context 实现共享数据存储的地方,是协程安全的。context 在业务中是经常被使用的,
应用 :
1:上下文控制,2:多个 goroutine 之间的数据交互等,3:超时控制:到某个时间点超时,过多久超时。
泛型使得Go语言更加灵活和强大,通过参数化类型,你可以编写更加通用和可复用的代码。泛型函数和泛型类型是泛型在Go中的两种主要应用方式,而类型约束则用来限制类型参数的范围,确保类型安全。掌握泛型将大大提高你的Go编程效率和代码质量。
type Number interface {
int | int64 | float64
}
func Add[T Number](a, b T) T {
return a + b
}
相同点:
不同点:
切片(Slice)在 Go 语言中,有一个很常用的数据结构,切片是一个拥有相同类型元素的可变长度的序列,它是基于数组类型做的一层封装。它非常灵活,支持自动扩容。并发不安全。
切片是一种引用类型,它有三个属性:指针,长度和容量
type slice struct {
array unsafe.Pointer
len int
cap int
}
1.指针: 指向 slice 可以访问到的第一个元素。
2.长度: slice 中元素个数。
3.容量: slice 起始元素到底层数组最后一个元素间的元素个数。
扩容时机:append时
1.18版本以前
1.18版本以后