GOROOT:Go 语言安装根目录的路径,也就是 GO 语言的安装路径。
GOPATH:若干工作区目录的路径。是我们自己定义的工作空间。
GOBIN:GO 程序生成的可执行文件(executable file)的路径。
Go各版本新特性
Go1.2
切片操作:
1 | var a = make([]int, 10) |
b
切片是从a
切片的第i
个元素开始到第j
个元素前结束,b
切片的容量为k
。
1 | func (v Value) SetCap(cap int) |
Value.SetCap
只调整切片的容量,等价于 a[::cap]
。Value.Slice3
切片操作同时也指定新切片的容量,等价于 a[low:high:max]
。
Go1.4
for
语句加强,Go1.3 之前 for
只有下面两种写法:
1 | for i, v := 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 | import "testing" |
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 | type Handler interface { |
interface
是一种类型,具有一组方法的类型,这些方法定义了 interface
的行为。
go 允许不带任何方法的 interface ,empty interface
。
如果一个类型实现了一个 interface 中所有方法,类型实现了该 interface,
Interface
interface
是一种类型,从定义中可以看出 type
关键字,更准确的说 interface
是一种具有一组方法的类型,这些方法定义了 interface 的行为。
Context
Context
(上下文),它是一个比较抽象的概念,一般理解为程序单元的一个运行状态。
Goroutine在执行之前,都要先知道程序当前的执行状态,通常将执行状态封装在一个Context
变量中,传递给要执行的Goroutine中。
context
包的核心就是Context
接口,定义如下:
1 | type Context 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 | type Reader interface { |
defer
当函数执行到最后时,defer语句会按照逆序执行,最后该函数返回。
1 | func ReadWrite() bool { |
Golang 需要避免踩的 50 个坑
- 左大括号 { 一般不能单独放一行
Go 遵守分号注入规则(automatic semicolon injection),编译器会在每行代码尾部特定分隔符后加 ; 来分隔多条语句,比如会在 ) 后加分号:
Go Plugin
Golang是静态编译型语言,编译时就将所有引用的包全部打包到最终的可执行程序中,因此并不能在运行时动态加载其他共享库。Go Plugin提供了这样一种方式,能够让你在运行时动态加载外部库。Plugin可以根据需要随时替换其中某些部件而不用修改程序。Plugin 可以和主程序独立建设,主程序只需要制定好框架,实现默认功能。Plugin 可根据用户需求随时自行扩展开发,运行时随意替换,提高了程序的可定制性;
1 | type Plugin struct{ ... } |
Plugin
即Golang加载的插件。
- Open 根据参数path提供的路径加载这个插件,并返回插件结构指针
- Lookup 通过名称在插件中寻找对应的变量或方法,以Symbol的形式返回
Symbol
是interface的别名,可以从插件里面拿到任何类型的可导出元素。
Reference :