Go中容易踩的坑

初级篇

  • 变量覆盖
    变量覆盖不会报错,检查方式:

      使用 vet 工具来诊断这种变量覆盖,Go 默认不做覆盖检查,添加 -shadow 选项来启用
      		go tool vet -shadow main.go
      vet 不会报告全部被覆盖的变量,可以使用 go‑nyet 来做进一步的检测
      		go-nyet main.go
    
  • 其它语言数组传参是引用/指针,go语言是值,但是slice虽然是值拷贝,但函数内部回改变slice的值。

      var a [3]int //数组
      var a []int //切片
    
  • string 类型的值是常量,不可更改

      string 类型的值是只读的二进制 byte slice
      如果真要修改字符串中的字符,将 string 转为 []byte 修改后,再转为 string 即可
    
// 修改示例
func main() {
x := "text"
xBytes := []byte(x)
xBytes[0] = 'T' // 注意此时的 T 是 rune 类型
x = string(xBytes)
fmt.Println(x) // Text
}
	更新字串的正确姿势:
	将 string 转为 rune slice(此时 1 个 rune 可能占多个 byte),直接更新 rune 中的字符
func main() {
x := "text"
xRunes := []rune(x)
xRunes[0] = '我'
x = string(xRunes)
fmt.Println(x) // 我ext
}
  • 字符串长度

      Go 的内建函数 len() 返回的是字符串的 byte 数量,而不是像 Python 中那样是计算 Unicode 字符数。
      如果要得到字符串的字符数,可使用 "unicode/utf8" 包中的 RuneCountInString(str string) (n int)
    
  • 多行 array、slice、map 语句中不能缺少“,”

  • 单行array、slice、map 最后一个不需要“,”

  • log.Fatal 和 log.Panic 不只是 log

func main() {
	log.Fatal("Fatal level log: log entry") // 输出信息后,程序终止执行
	log.Println("Nomal level log: log entry")
}
  • 自增和自减运算

      Go 特立独行,去掉了前置操作,同时 ++ 、 — 只作为运算符而**非表达式**。
    
  • 按位取反

      取反:^
      二元XOR:^
      AND NOT &^ 操作符,不同位才取1
    
  • 优先级列表

      Precedence 		Operator
      5 				* / % << >> & &^
      4				 	+ - | ^
      3 				== != < <= > >=
      2 				&&
      1 				||
    
  • 不导出的 struct 字段无法被 encode

      以小写字母开头的字段成员是无法被外部直接访问的
      所以 struct 在进行 json、xml、gob 等格式的encode 操作时,这些私有字段会被忽略,导出时得到零值。
    
  • 程序退出时还有 goroutine 在执行

      使用sync.WaitGroup来控制
      var wg sync.WaitGroup
      wg.Add(1)
      wg.Wait()
    
  • 向无缓冲的 channel 发送数据,只要 receiver 准备好了就会立刻返回

中级篇

  • 待更新
发布了40 篇原创文章 · 获赞 26 · 访问量 7678

猜你喜欢

转载自blog.csdn.net/weixin_44879611/article/details/104729283