Go: 开发过程中的一些bug
1. make slice
很容易漏掉中间参数, 引入 bug并且很难排查
package main
import "fmt"
func doCopy(a []string) []string {
b := make([]string, len(a))
for _, i := range a {
b = append(b, i)
}
return b
}
func main() {
a := []string{"hello"}
b := doCopy(a)
fmt.Println(b, len(b))
}
得到结果
[ hello] 2
实际上
a := make([]int, 5) // len(a)=5
a := make([]int, 0, 5) // len(a)=0 cap(b)=5
2. shadow
本来应该使用=
赋值, 错误地使用了:=
(这个govet可以扫出来)
var form url.Values
if checkForm {
form := make(url.Values)
util.CopyValues(form, r.PostForm)
}
3. err == or !=
容易敲错, 且不好排查
if err == nil {
}
if err != nil {
}
4. 漏掉了return
在本该return的地方漏掉了, 导致逻辑继续往后走, 这种在gin的handler和middleware特别容易漏
if err != nil {
render.JSON(w, err.Status, err)
// 这里漏掉了 return
}
next.ServeHTTP(w, r)
5. scopelint
package main
import "fmt"
func main() {
values := []string{"a", "b", "c"}
var copies []*string
for _, val := range values {
copies = append(copies, &val)
}
fmt.Println(copies)
}
此时得到
[0xc000010200 0xc000010200 0xc000010200]
预期的应该是
package main
import "fmt"
func main() {
values := []string{"a", "b", "c"}
var copies []*string
for _, val := range values {
// add := here
val := val
copies = append(copies, &val)
}
fmt.Println(copies)
}
6. error.Is放错了位置
if err != nil {
return err
}
...
if error.Is(err, DEMOError) {
// will never execute
}
7. close the connection
// the connection is not close
_, err := sqlx.Connect("mysql", db.dataSource)
// should be
conn, err := sqlx.Connect("mysql", db.dataSource)
if err != nil {
return
}
conn.Close()