GOROOT:Go 语言安装根目录的路径,也就是 GO 语言的安装路径。

GOPATH:若干工作区目录的路径。是我们自己定义的工作空间。

GOBIN:GO 程序生成的可执行文件(executable file)的路径。


Go各版本新特性

Go1.2

切片操作:

1
2
var a = make([]int, 10)
var b = a[i:j:k]

b切片是从a切片的第i个元素开始到第j个元素前结束,b切片的容量为k

1
2
func (v Value) SetCap(cap int)
func (v Value) Slice3(low, high, max int) Value

Value.SetCap 只调整切片的容量,等价于 a[::cap]
Value.Slice3 切片操作同时也指定新切片的容量,等价于 a[low:high:max]

Go1.4

for 语句加强,Go1.3 之前 for 只有下面两种写法:

1
2
3
4
5
6
7
for i, v := range x {
// ...
}

for i := range x {
// ...
}

Go1.7

Go1.8

Go1.9


Testing in Go by example

All you have to do is create a file named like *_test.go, and start with something like this:

1
2
3
4
5
import "testing"

func TestSomething(t *testing.T) {
// test stuff here...
}

test function starts with Test... and receives a single parameter: t *testing.T. t.Fail() make test failed, t.Error() throw a error, t.Log() take a log output.

go test -v testing runs the actual tests for the “testing” package from the standard library.

go test -v testing encoding/json running multiple packages with a single command.

go test -v -run=TestBowlingGameScoring


Golang必备技巧:接口型函数

接口型函数,函数实现接口。

1
2
3
4
5
6
7
8
9
10
11
type Handler interface {
Work(k, v interface{})
}

func Each(m map[interface{}]interface{}, h Handler) {
if m != nil && len(m) > 0 {
for k, v := range m {
h.Work(k, v)
}
}
}

interface 是一种类型,具有一组方法的类型,这些方法定义了 interface 的行为。

go 允许不带任何方法的 interface ,empty interface

如果一个类型实现了一个 interface 中所有方法,类型实现了该 interface,


Interface


Context

Context(上下文),它是一个比较抽象的概念,一般理解为程序单元的一个运行状态。

Goroutine在执行之前,都要先知道程序当前的执行状态,通常将执行状态封装在一个Context变量中,传递给要执行的Goroutine中。

context包的核心就是Context接口,定义如下:

1
2
3
4
5
6
type Context interface {
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{}
Err() error
Value(key interface{}) interface{}
}

Deadline会返回一个超时时间,Goroutine获得了超时时间后,例如可以对某些io操作设定超时时间。

Done方法返回一个信道(channel),当Context被撤销或过期时,该信道是关闭的,即它是一个表示Context是否已关闭的信号。

Done信道关闭后,Err方法表明Context被撤的原因。

Value可以让Goroutine共享一些数据,当然获得数据是协程安全的。但使用这些数据的时候要注意同步,比如返回了一个map,而这个map的读写则要加锁。

Programs that use Contexts should follow these rules to keep interfaces consistent across packages and enable static analysis tools to check context propagation:

  • Do not store Contexts inside a struct type; instead, pass a Context explicitly to each function that needs it. The Context should be the first parameter, typically named ctx;
  • Do not pass a nil Context, even if a function permits it. Pass context.TODO if you are unsure about which Context to use;
  • Use context Values only for request-scoped data that transits processes and APIs, not for passing optional parameters to functions;
  • The same Context may be passed to functions running in different goroutines; Contexts are safe for simultaneous use by multiple goroutines;

IO 包中最重要的是两个接口:Reader 和 Writer 接口。

1
2
3
4
5
6
7
8
9
10
11
type Reader interface {
// 将 len(p) 个字节读取到 p 中。
// 它返回读取的字节数 n(0 <= n <= len(p)) 以及任何遇到的错误。
Read(p []byte) (n int, err error)
}

type Writer interface {
// 将 len(p) 个字节从 p 中写入到基本数据流中。
// 返回从 p 中被写入的字节数 n(0 <= n <= len(p))以及任何遇到的引起写入提前停止的错误。
Write(p []byte) (n int, err error)
}

defer

当函数执行到最后时,defer语句会按照逆序执行,最后该函数返回。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func ReadWrite() bool {
file.Open("file")
if failureX {
file.Close()
return false
}

if failureY {
file.Close()
return false
}

file.Close()
return true
}

Reference :

  1. Testing in Go by example
  2. Golang必备技巧:接口型函数
  3. 理解 Go interface 的 5 个关键点
  4. The Way to Go 中文译本
  5. Go语言标准库 The Golang Standard Library by Example
  6. Go语言高级编程(Advanced Go Programming)
  7. Go2编程指南
  8. Go语言回顾:从Go 1.0到Go 1.13
  9. GO 命令教程