Golang的并发原语为构造并发软件提供了一种优雅而独特的手段。Go鼓励使用channels和goroutines之间传递对数据的引用,而不是显示地使用锁来调解对共享数据的访问。这种方法确保只有一个goroutine可以在给定的时间访问数据。

    并发不是并行(Concurrency is not parallelism)
    在编程中,并发是独立执行的进程的组成,而并行则是计算的同时执行。并发是一次处理很多事情,并行是一次做很多事情。

    chanels重排序;互斥量串行化(Channels orchestrate; mutexes serialize)

    1. package main
    2. import "fmt"
    3. func sum(s []int, c chan int) {
    4. sum := 0
    5. for _, v := range s {
    6. sum += v
    7. }
    8. c <- sum // 此处如果改成互斥量一样可以做到
    9. }
    10. func main() {
    11. s := []int{7, 2, 8, -9, 4, 0}
    12. c := make(chan int)
    13. go sum(s[:len(s)/2], c)
    14. go sum(s[len(s)/2:], c)
    15. x, y := <-c, <-c
    16. fmt.Println(x, y, x+y)
    17. }

    接口越大,抽象越弱(The bigger the interface, the weaker the abstraction)
    接口背后的概念是通过将对象的行为抽象为简单的契约来允许重用性。虽然接口不是Go专有的,但是由于Go接口通常趋向于小型化,Go程序员才广发使用它们。通常情况下,一个接口只限于一到两个方法。

    充分利用零值(Make the zero value useful)

    1. type Map struct {
    2. mu sync.RWMutex
    3. // ...}
    4. func (m *Map) Set(k, v interface{}) {
    5. m.mu.Lock()
    6. defer m.mu.Unlock()
    7. if m.m == nil {
    8. m.m = make(map[interface{}]interface{})
    9. }
    10. m.m[k] = v
    11. }

    interface{} 言之无物(interface{} says nothing)
    不是说interface{}不代表任何东西,而是说该类型无静态检查以及调用时保证。

    小复制好过小依赖(A little copying is better than a little dependency)

    1. package main
    2. import ( "fmt"
    3. "os")
    4. func main() {
    5. f, _ := os.Open("/dev/urandom") // 演示用忽略 errcheck
    6. b := make([]byte, 16)
    7. f.Read(b)
    8. f.Close()
    9. uuid := fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
    10. fmt.Println(uuid)
    11. }

    系统调用必须始终使用构建标签保证(Syscall must always be guared with build tags)
    不同的系统 (*NIX, Windows) 调用导致你同一个 func (实现并不一样) 可能需要在不同的系统上构建才能得到你想要的结果. 简单说就是系统调用不可移植才这么干. 示例可参见 Go 标准库 syscall.

    Cgo必须使用使用构建标签保证(Cgo must always be guared with build tags)
    Cgo不是go。如果可能不要用Cgo。

    unsafe包无保证(With the unsafe package there are no guarantees)
    包如其名, 不安全. 你可以使用 unsafe 包如果你准备好了有一天它会坏掉.

    清晰好过聪明(Clear is better than clever)
    写清晰的代码,不要写聪明的代码

    反射永远不是清晰的(Reflection is never clear)
    很多人抱怨 Go 的反射不工作, 因为那不是为你准备的


    Go 谚语 - 图1