defer
1 、 当 defer 语句被执行时,跟在 defer 后面的函数会被延迟执行。直到包含该 defer 语句的函数执行完毕时,defer 后的函数才会被执行,不论包含defer 语句的函数是通过 return 正常结束,还是由于 panic 导致的异常结束。
2、在一个函数中执行多条 defer 语句,defer的执行顺序与声明顺序相反。
使用场景:
1)defer语句经常被用于处理成对的操作,如打开、关闭、连接、断开连接、加锁、释放锁。
2)通过defer机制,不论函数逻辑多复杂,都能保证在任何执行路径下,资源被释放。
3)释放资源的defer 应该直接跟在请求资源的语句后。
切片扩容
1、GoLang中的切片扩容机制,与切片的数据类型、原本切片的容量、所需要的容量都有关系。对于常见数据类型,在元素数量较少时,大致可以认为扩容是按照翻倍进行的。但具体情况需要具体分析。
2、为了避免因为切片是否发生扩容的问题导致bug,最好的处理办法还是在必要时使用 copy 来复制数据,保证得到一个新的切片,以避免后续操作带来预料之外的副作用。
// 当原切片长度小于1024时,新切片的容量会直接翻倍。而当原切片的容量大于等于1024时,会反复地增加25%,直到新容量超过所需要的容量
func main() {
arr := make([]int, 0)
for i := 0; i < 2000; i++ {
fmt.Println("len 为", len(arr), "cap 为", cap(arr))
arr = append(arr, i)
}
}
数组和切片
数组:
1、长度固定
2、需要指定数组大小,不指定的情况下会根据初始化自动推算出大小
3、值传递
切片:
1、长度可变
2、不需要指定大小
3、地址(引用)传递
4、可以通过数组来初始化,也可以通过内置函数 make()来初始化,初始化的时候 len=cap,然后进行扩容
channel
1、如果给一个 nil 的 channel 发送数据,会造成永远阻塞。
2、如果从一个 nil 的 channel 中接收数据,也会造成永久阻塞。
3、给一个已经关闭的 channel 发送数据, 会引起 panic
4、从一个已经关闭的 channel 接收数据, 如果缓冲区中为空,则返回一个零值。
5、无缓冲的 channel 是同步的,而有缓冲的 channel 是非同步的
new 和 make
new:
1、作用是初始化一个内置类型的指针, new 函数是内建函数
2、函数定义:func new(Type) *Type
3、使用 new 函数来分配空间
4、传递给 new 函数的是一个类型,而不是一个值
5、返回值是指向这个新分配的地址的指针
make:
1、作用是为 slice, map or chan 的初始化, 然后返回引用, make 函数是内建函数
2、函数定义:func make(Type, size IntegerType) Type
3、仅仅用于创建 slice, map, channel
4、返回类型是实例