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
5-things-rob-pike-attributes-to-gos-success
4 Vim-Go
Vim and ONLY Vim.
plugin 'fatih/vim-go' :GoInstallBinaries :help vim-go
如果执行 :GoInstallBinaries
报错, 请参考 go_get_timeout_solution
5 Go Style
规范, 约定大于配置, 好的习惯比什么都重要.
6 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) }) }) }) }
6.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
查看更多信息.
参考自 StackOverflow: How to run test cases in a specified file? 和 这里, 我的源码例子: 这里
6.2 Mock
学会mock方法. 考察了很多 mock 的插件, 如 testify/mock, Gomock, Gostub 等, 最终我们选择了 testify/mock
Golang 的 mock, 不像面向对象语言, 她只能对 interface 进行mock. 有人对此也提出了疑问, 详情请见 How to write mock for structs in Go
代码请见我的mock_test
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 是可以被使用的
Types: bool byte complex64 complex128 error float32 float64 int int8 int16 int32 int64 rune string uint uint8 uint16 uint32 uint64 uintptr Constants: true false iota Zero value: nil Functions: append cap close complex copy delete imag len make new panic print println real recover
如下面的语法是Okay的
bool := 1 fmt.Println(bool)
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 resliced 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
go help
8.3 Go Tags in structures
- What are the use(s) for tags in Go?
- Spec#Struct_types
- Sam Helman & Kyle Erf - The Many Faces of Struct Tags
9 并发
9.1 sync Package
10 其他
11 项目
11.1 Go Strings
用Go语言做跟音乐相关的东西, 正在筹划中