More: More Dengqinghua

Go 学习

2018-06-05

该部分包含了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 Vim-Go

Vim and ONLY Vim.

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

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

4 Go Style

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

5 Test

TDD

最终选择的是 Goconvey

测试Case如下:

package golang

import (
    . "github.com/smartystreets/goconvey/convey"
    "testing"
)

// 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)
            })
        })
    })
}

5.1 Test Func

测试单独的一个方法

hello_world.go

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
}

hello_world_test.go

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

测试全部的case

go test

测试某个case

go test -run TestSum

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

5.2 Mock

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

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

代码请见我的mock_test

6 Debugger

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

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

delve-demo

7 基础知识

package main
import "fmt"

var a = 1

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

7.1 GoPath

Code organization

go help

7.2 Go Tags in structures

8 并发

9 其他

10 项目

10.1 Go Strings

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

11 Books