13.a - wwj-2017-1117/AES_OK GitHub Wiki

1)使用case

2)使用if-1 go str, ok := value.(string) if ok { fmt.Printf("string value is: %q\n", str) } else { fmt.Printf("value is not a string\n") }

3)使用If-2 go if str, ok := value.(string); ok { return str } else if str, ok := value.(Stringer); ok { return str.String() }

  1. map-1 go 判断方式为value,ok := map[key], ok为true则存在
  2. map-2

错误的2种定义方法 func testError1() error{ k:="test1108" return fmt.Errorf("test error %s",k) } func testError2() error{ return errors.New("test error") }

  1. waitGroup中的坑 https://liudanking.com/golang/golang-waitgroup-usage/

总结: 1) WaitGroup 同步的是 goroutine, 因此add操作是在goroutine外部执行,而Done操作是在goroutine内问完成。 2) waitGroup 传递的是地址

正确的写法:

go import ( "log" "sync" )

func main() { wg := &sync.WaitGroup{}

for i := 0; i < 5; i++ { wg.Add(1) go func(wg *sync.WaitGroup, i int) { log.Printf("i:%d", i) wg.Done() }(wg, i) }

wg.Wait()

log.Println("exit") }

  1. 闭包 从形式上看,在Golang中,所有的匿名函数都是闭包。闭包的创建方式和普通函数几乎一致,只有一个关键区别:闭包没有名字

参考:Golang 中关于闭包的坑https://www.jianshu.com/p/fa21e6fada70 https://blog.csdn.net/qq_35976351/article/details/81986496

闭包的本质:https://blog.51cto.com/speakingbaicai/1703229

错误的代码片断:

`go func main() { var wg sync.WaitGroup

// wg := &sync.WaitGroup{}

for i := 0; i < 5; i++ { wg.Add(1) go func(wg *sync.WaitGroup) { log.Printf("i:%d", i) wg.Done() }(&wg) }

wg.Wait()

log.Println("exit") }

`

输出结果:

` 2019/07/31 10:22:26 i:5 2019/07/31 10:22:26 i:5 2019/07/31 10:22:26 i:5 2019/07/31 10:22:26 i:5 2019/07/31 10:22:26 i:5 2019/07/31 10:22:26 exit

`

正确的写法:

func main() { var wg sync.WaitGroup

//wg := &sync.WaitGroup{}

for i := 0; i < 5; i++ { wg.Add(1) go func(wg *sync.WaitGroup, j int) { log.Printf("i:%d", j) wg.Done() }(&wg, i) }

wg.Wait()

log.Println("exit") }

`

解释:这种现象的原因在于闭包共享外部的变量i,注意到,每次调用go就会启动一个 goroutine,这需要一定时间; 但是,启动的goroutine与循环变量递增不是在同一个goroutine,可以把i认为处于主goroutine中。 同时启动一个goroutine的速度远小于循环执行的速度,所以即使是第一个goroutine刚起启动时,外层的循环也执行到了最后一步了。 由于所有的goroutine共享i,而且这个i会在最后一个使用它的goroutine结束后被销毁,所以最后的输出结果都是最后一步的i==5。

12 . defer defer的执行顺序是在return调用之后,但是仍然在函数之内。

  1. reflect.DeepEqual https://studygolang.com/articles/2194

16.Golang中的time.After的使用理解 https://studygolang.com/articles/10229

  1. unsafe.Pointer 18 . 使用 validate来校验数据,分析原理,本地调试 `go err := validator.Validate(container) var limitErr = false

使用perfmap代替concurrentmap.

带omitemty的情况下,如果字段的值为该字段类型的go语言默认值,比如int为0,string为空等情况,则该字段将被Json串忽略丢弃。