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() }
- map-1 go 判断方式为value,ok := map[key], ok为true则存在
- 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 同步的是 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") }
- 闭包 从形式上看,在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调用之后,但是仍然在函数之内。
- reflect.DeepEqual https://studygolang.com/articles/2194
16.Golang中的time.After的使用理解 https://studygolang.com/articles/10229
- unsafe.Pointer 18 . 使用 validate来校验数据,分析原理,本地调试 `go err := validator.Validate(container) var limitErr = false
使用perfmap代替concurrentmap.
带omitemty的情况下,如果字段的值为该字段类型的go语言默认值,比如int为0,string为空等情况,则该字段将被Json串忽略丢弃。