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

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()

golang

389 Words

2021-01-28 00:00 +0000