Go 语法速览与实践清单
作者:媒体转发 时间:2018-04-15 09:44
Go CheatSheet 是对于 Go 学习/实践过程中的语法与技巧进行盘点,其属于 Awesome CheatSheet 系列,致力于提升学习速度与研发效能,即可以将其当做速查手册,也可以作为轻量级的入门学习资料。 本文参考了许多优秀的文章与代码示范,统一声明在了 Go Links;如果希望深入了解某方面的内容,可以继续阅读 Go 开发:语法基础与工程实践,或者前往 coding-snippets/go 查看使用 Go 解决常见的数据结构与算法、设计模式、业务功能方面的代码实现。

环境配置与语法基础
可以前往这里下载 Go SDK 安装包,或者使用 brew 等包管理器安装。go 命令依赖于 $GOPATH 环境变量进行代码组织,多项目情况下也可以使用 ln 进行目录映射以方便进行项目管理。GOPATH 允许设置多个目录,每个目录都会包含三个子目录:src 用于存放源代码,pkg 用于存放编译后生成的文件,bin 用于存放编译后生成的可执行文件。
环境配置完毕后,可以使用 go get 获取依赖,go run 运行程序,go build 来编译项目生成与包名(文件夹名)一致的可执行文件。Golang 1.8 之后支持 dep 依赖管理工具,对于空的项目使用 dep init 初始化依赖配置,其会生成 Gopkg.toml Gopkg.lock vendor/这三个文件(夹)。
我们可以使用 dep ensure -add github.com/pkg/errors 添加依赖,运行之后,其会在 toml 文件中添加如下锁:
[[constraint]]
name = "github.com/pkg/errors"
version = "0.8.0"
简单的 Go 中 Hello World 代码如下:
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
也可以使用 Beego 实现简单的 HTTP 服务器:
package main
import "github.com/astaxie/beego"
func main() {
beego.Run()
}
Go 并没有相对路径引入,而是以文件夹为单位定义模块,譬如我们新建名为 math 的文件夹,然后使用 package math 来声明该文件中函数所属的模块。
import (
mongo "mywebapp/libs/mongodb/db" // 对引入的模块重命名
_ "mywebapp/libs/mysql/db" // 使用空白下划线表示仅调用其初始化函数
)
外部引用该模块是需要使用工作区间或者 vendor 相对目录,其目录索引情况如下:
cannot find package "sub/math" in any of:
${PROJECTROOT}/vendor/sub/math (vendor tree)
/usr/local/Cellar/go/1.10/libexec/src/sub/math (from $GOROOT)
${GOPATH}/src/sub/math (from $GOPATH)
Go 规定每个源文件的首部需要进行包声明,可执行文件默认放在 main 包中;而各个包中默认首字母大写的函数作为其他包可见的导出函数,而小写函数则默认外部不可见的私有函数。
表达式与控制流
变量声明与赋值
作为强类型静态语言,Go 允许我们在变量之后标识数据类型,也为我们提供了自动类型推导的功能。
// 声明三个变量,皆为 bool 类型
var c, python, java bool
// 声明不同类型的变量,并且赋值
var i bool, j int = true, 2
// 复杂变量声明
var (
ToBe bool = false
MaxInt uint64 = 1<<64 - 1
z complex128 = cmplx.Sqrt(-5 + 12i)
)
// 短声明变量
c, python, java := true, false, "no!"
// 声明常量
const constant = "This is a constant"
在 Go 中,如果我们需要比较两个复杂对象的相似性,可以使用 reflect.DeepEqual 方法:
m1 := map[string]int{
"a":1,
"b":2,
}
m2 := map[string]int{
"a":1,
"b":2,
}
fmt.Println(reflect.DeepEqual(m1, m2))
条件判断
Go 提供了增强型的 if 语句进行条件判断:
// 基础形式
if x > 0 {
return x
} else {
return -x
}
// 条件判断之前添加自定义语句
if a := b + c; a < 42 {
return a
} else {
return a - 42
}
// 常用的类型判断
var val interface{}
val = "foo"
if str, ok := val.(string); ok {
fmt.Println(str)
}
Go 也支持使用 Switch 语句:
// 基础格式
switch operatingSystem {
case "darwin":
fmt.Println("Mac OS Hipster")
// 默认 break,不需要显式声明
case "linux":
fmt.Println("Linux Geek")
default:
// Windows, BSD, ...
fmt.Println("Other")
}
// 类似于 if,可以在条件之前添加自定义语句
switch os := runtime.GOOS; os {
case "darwin": ...
}
// 使用 switch 语句进行类型判断:
switch v := anything.(type) {
case string:
fmt.Println(v)
case int32, int64:
...
default:
fmt.Println("unknown")
}
Switch 中也支持进行比较:
number := 42
switch {
case number < 42:
fmt.Println("Smaller")
case number == 42:
fmt.Println("Equal")
case number > 42:
fmt.Println("Greater")
}
或者进行多条件匹配:
var char byte = '?'
switch char {



