初级篇
-
变量覆盖
变量覆盖不会报错,检查方式:使用 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 准备好了就会立刻返回
中级篇
- 待更新