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语言做跟音乐相关的东西, 正在筹划中
