More: More Dengqinghua

Go 学习




1 提问的智慧

如何提问很重要, 在学习任何知识之前, 需要先学会正确地提问.

  • 提问的智慧原文: 这里
  • 提问的智慧中文版本: 这里

2 Go Proverbs

Simple, Poetic, Pithy

Go Proverbs - Rob Pike - Gopherfest

  • Don't communicate by sharing memory, share memory by communicating.
  • Concurrency is not parallelism.
  • Channels orchestrate; mutexes serialize.
  • The bigger the interface, the weaker the abstraction.
  • Make the zero value useful.
  • interface{} says nothing.
  • Gofmt's style is no one's favorite, yet gofmt is everyone's favorite. WHO CARES? SHUT UP
  • A little copying is better than a little dependency.
  • Syscall must always be guarded with build tags.
  • Cgo must always be guarded with build tags.
  • Cgo is not Go.
  • With the unsafe package there are no guarantees.
  • Clear is better than clever.
  • Reflection is never clear.
  • Errors are values.
  • Don't just check errors, handle them gracefully.
  • Design the architecture, name the components, document the details.
  • Documentation is for users.
  • Don't panic.

3 5 things of Go's success

As the saying goes... history doesn’t repeat itself, but it often rhymes.

  • Formal specification
  • Attracted killer apps (Docker, k8s)
  • the Open source community
  • Made the language hard to change
  • Stuck with features they believed in


4 Vim-Go

Vim and ONLY Vim.

plugin 'fatih/vim-go'
:help vim-go

如果执行 :GoInstallBinaries 报错, 请参考 go_get_timeout_solution

5 Go Style

规范, 约定大于配置, 好的习惯比什么都重要.

6 Test


最终选择的是 Goconvey


package golang

import (
    . ""

// go test -v -run TestBasicMap
func TestBasicMap(t *testing.T) {
    Convey("TestBasicMap", t, func() {
        Convey("get, put", func() {
            Convey("should get right", func() {
                oneMap := make(map[string]int)

                oneMap["dsgv"] = 587

                value, exist := oneMap["dsgv"]

                So(exist, ShouldBeTrue)
                So(value, ShouldEqual, 587)

                value, exist = oneMap["dsg"]

                So(exist, ShouldBeFalse)
                So(value, ShouldEqual, 0)

6.1 Test Func



package main

// go run hello_world.go
// go build hello_world.go
// :GoRun / :GoBuild
func main() {
    println(Sum(5, 5))

func Sum(x int, y int) int {
    return x + y


package main

import "testing"

// go test -run TestSum
func TestSum(t *testing.T) {
    total := Sum(5, 5)

    if total != 5 {
        // t.Errorf; t.Fail; t.Log
        t.Errorf("Sumw was incorrect, got %d, want %d", total, 10)

// go test -run TestSum1
func TestSum1(t *testing.T) {
    total := Sum(5, 5)

    if total != 6 {
        // t.Errorf; t.Fail; t.Log
        t.Errorf("Sumw was incorrect, got %d, want %d", total, 10)


go test


go test -run TestSum

test文件必须写成 *_test 的形式. 可以执行 go help test 查看更多信息.

6.2 Mock

学会mock方法. 考察了很多 mock 的插件, 如 testify/mock, Gomock, Gostub 等, 最终我们选择了 testify/mock

Golang 的 mock, 不像面向对象语言, 她只能对 interface 进行mock. 有人对此也提出了疑问, 详情请见 How to write mock for structs in Go


7 Debugger

学会调试, 查看源码, 阅读源码.

由于 Vim Godebug 依赖 Neovim, 而我们一般使用的是vim, 故最终选择的调试工具为 sebdah/vim-delve, vim-delve 依赖 Shougo/vimshell.vim.


8 基础知识

package main
import "fmt"

var a = 1

func main() {
  fmt.Println("Hello World")

8.1 Spec部分笔记

8.1.1 Predeclared Identifiers and Keywords

Predeclared Identifiers 是可以被使用的

    bool byte complex64 complex128 error float32 float64
    int int8 int16 int32 int64 rune string
    uint uint8 uint16 uint32 uint64 uintptr

    true false iota

Zero value:

    append cap close complex copy delete imag len
    make new panic print println real recover


bool := 1

Keywords 是不可以被重复使用的, 包括下面这些

break        default      func         interface    select
case         defer        go           map          struct
chan         else         goto         package      switch
const        fallthrough  if           range        type
continue     for          import       return       var

8.1.2 Slice

A slice is

  • a data structure describing a contiguous section of an array stored separately from the slice variable itself
  • a data structure with two elements: a length and a pointer to an element of an array
type sliceHeader struct {
    Length        int
    Capacity      int
    ZerothElement *byte

A slice cannot be grown beyond its capacity. Attempting to do so will cause a runtime panic. Similarly, slices cannot be re­sliced below zero to access earlier elements in the array.

8.1.3 Rune

A rune literal represents a rune constant, an integer value identifying a Unicode code point, or think of as a character constant is called a rune constant in Go.

Strings, bytes, runes and characters in Go

  • A string is in effect a read-only slice of bytes


8.2 GoPath

Code organization

go help

8.3 Go Tags in structures

9 并发

9.1 sync Package

10 其他

11 项目

11.1 Go Strings

用Go语言做跟音乐相关的东西, 正在筹划中

12 Books