go容易犯错的30个陷阱

「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!前端

当心指针的陷阱

image.png

  1. tom是指向user的指针,name=tom
  2. tom赋值给jack
  3. jack修改name=jack
  4. tom.name也变为jack

struct赋值的顺序

image.png age虽然在name以前,可是由于name是函数fmt.Sprintf的返回值,因此在初始化user的时候,会先处理成员变量是表达式的返回值的。golang

defer panic return的顺序

image.png do something->do defer->panicjson

image.png do something->do defer->return后端

json number反射到interface的坑

image.png json number反射到interface上,这时经过断言为int是错误的,此时interface断言是float64。数组

当心for循环临时变量和goroutine组合的坑

image.png i是临时变量,当每一个goroutine抢着去打印i的时候,其结果是不肯定的,每一个gourotine运行到的时候,i当前是什么,就打印什么。markdown

range一个chan的时候,记得在close,否则会deadlock

image.png

map是要初始化的,否则会报nil map

image.png

从map中取不存在key的时候,返回的是对应的零值

image.png 能够经过if v,ok := x["two"]; ok来判断app

byte和rune傻傻分不清楚

image.png byte表示字节,一个中文正常3个字节,rune用来表示Unicode的码点,即一个字符。函数

代码块内同名变量的修改,不会影响代码块外的值

image.png

range map是无序的

image.png

nil != nil

image.png 当心nil != nil的陷阱。golang的interface是由两个部分组成的,{Type, Value},a至关于{nil,nil},b至关于{*int,nil},a天然不等于b。post

当心你的类型溢出

image.png 这里其实会卡住,首先byte本质是uint8,最大值是255,当到达255后,先加1,就会发生溢出,回到0,因此这行代码本质就是个for{}ui

给一个已经close的channel发数据会panic

image.png

从一个已经close的channel收数据会收到零值

image.png

经过context timeout来控制超时

image.png

make和new的区别

image.png 经过定义能够看出new返回的是指针,make返回的类型的值。make能够是slice、map和chan,new能够new一个类型。

append扩容致使的底层数组的变化

image.png 最后一次append,原数组容量不够,从新分配数组。地址变化。

go抢占式调度

image.png 在只有一个处理器的状况下,即便一个goroutine是死循环,它也不会一直执行下去

select的随机性

image.png

无缓冲和有缓冲的chan的区别

image.png 无缓冲的chan,是同步阻塞的,必须存在某个时刻,在写的同时,另外一个已经在准备接收了。带缓冲的chan,在缓冲区没满的时候,是不阻塞的。

... 来接收可变长参数

image.png

尽可能使用小内存字段

image.png 根据所需,选择合理的类型,对GC友好。

空struct不占空间

image.png

两个无符号的数字最好不要相减,不会获得负数

image.png

go的strcut是能够比较的

image.png

map、slice、func不可比较,除非是nil

image.png

注意close你的http body,防止内存泄露

image.png

注册recover,防止panic致使的程序意外退出

image.png

go 语句后面的函数调用,其参数会先求值

image.png 因此以上会deadlock

相关文章
相关标签/搜索