

age虽然在name之前,但是因为name是函数fmt.Sprintf的返回值,所以在初始化user的时候,会先处理成员变量是表达式的返回值的。
defer panic return的顺序
do something->do defer->panic

do something->do defer->return
json number反射到interface的坑
json number反射到interface上,这时通过断言为int是错误的,此时interface断言是float64。
小心for循环临时变量和goroutine组合的坑
i是临时变量,当每个goroutine抢着去打印i的时候,其结果是不确定的,每个gourotine运行到的时候,i当前是什么,就打印什么。
range一个chan的时候,记得在close,不然会deadlock


可以通过if v,ok := x["two"]; ok来判断
byte和rune傻傻分不清楚
byte表示字节,一个中文正常3个字节,rune用来表示Unicode的码点,即一个字符。
代码块内同名变量的修改,不会影响代码块外的值


小心nil != nil的陷阱。golang的interface是由两个部分组成的,{Type, Value},a相当于{nil,nil},b相当于{*int,nil},a自然不等于b。
小心你的类型溢出
这里其实会卡住,首先byte本质是uint8,最大值是255,当到达255后,先加1,就会发生溢出,回到0,所以这行代码本质就是个for{}
给一个已经close的channel发数据会panic



通过定义可以看出new返回的是指针,make返回的类型的值。make可以是slice、map和chan,new可以new一个类型。
append扩容导致的底层数组的变化
最后一次append,原数组容量不够,重新分配数组。地址变化。
go抢占式调度
在只有一个处理器的情况下,即使一个goroutine是死循环,它也不会一直执行下去
select的随机性

无缓冲的chan,是同步阻塞的,必须存在某个时刻,在写的同时,另一个已经在**接收了。带缓冲的chan,在缓冲区没满的时候,是不阻塞的。
... 来接收可变长参数

根据所需,选择合理的类型,对GC友好。
空struct不占空间






所以以上会deadlock
