Golang 开发入门

安装

1
2
3
4
5
brew install go
go env

# brew 切换版本
# https://stackoverflow.com/questions/3987683/homebrew-install-specific-version-of-formula/4158763#4158763

配置

1
2
3
4
5
6
7
export GOVERSION=$(brew list go | head -n 1 | cut -d '/' -f 6)

export GOROOT=$(brew --prefix)/Cellar/go/$GOVERSION/libexec

export GOPATH=$HOME/Applications/Go:[GO-WORKSPACE]

export PATH=$PATH:$GOROOT/bin

GOROOT

Go语言编译、工具、标准库等的安装路径

GOPATH

工作目录,Go 使用第一个路径作为外部依赖的安装目录,多个路径使用冒号分割,主要包含三个目录:

  • bin 可执行文件
  • pkg 编译好的库文件(*.a)
  • src 源代码,大的工作空间,可以包含多个项目

开发工具

墙裂推荐 VSCode 作为 Golang 的开发工具! 在插件库中搜索并安装 Go 的集成开发环境

VSCode 各种技巧 https://github.com/Microsoft/vscode-tips-and-tricks/blob/master/README.md

tips: 在 VScode 的工作区 .vscode/settings.json 设置 gopath,就可以愉快的读库源码了

1
2
3
4
// 使用绝对路径,第一个为外部依赖安装目录,第二个为当前工作空间
{
"go.gopath": "[$HOME/Applications/Go]:[CURRENT-WORKSPACE]"
}

开发流程

新建工程

1
2
3
4
5
6
7
8
9
10
11
cd [WORKSPACE]

mkdir go-test

# 示例代码仅设置临时 gopath
export GOPATH=/Users/ZoeAllen/Applications/Go:[WORKSPACE]/go-test

mkdir src pkg bin
mkdir src/thewaytogo

vim src/thewaytogo/main.go

示例代码

1
2
3
4
5
6
7
package main

import "fmt"

func main(){
fmt.Println("hello world.")
}

运行方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 直接运行
go run src/thewaytogo/main.go

# 打包运行
cd src/ && go install thewaytogo
../bin/thewaytogo

# 交叉编译
# Mac 下编译 Linux 和 Windows 64位可执行程序
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go

# Linux 下编译 Mac 和 Windows 64位可执行程序
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build main.go
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go

# Windows 下编译 Mac 和 Linux 64位可执行程序 (略)
...

# 其他再议...

安装依赖

1
2
3
4
5
6
7
8
9
10
11
package main

import (
"fmt"
uuid "github.com/satori/go.uuid"
)

func main(){
fmt.Println("hello world.")
fmt.Println(uuid.NewV1().String())
}

示例代码中引用了 uuid 第三方库,使用 uuid 作为引用库的别名 (import 的机制不在这里展开)

1
2
3
4
5
6
7
go get github.com/satori/go.uuid

# 或者“高级”

go get ./...

go run main.go

第三方库

常见问题

  • 类型转换:Golang 是强类型语言,虽然 interface 大法好,必须清楚自己定义的类型,避免在运行时发生错误的转换或引用
  • 作用域:通过 := 定义的局部变量会覆盖同名的全局变量,然后炸了
  • 切记使用 defer 释放打开的资源
  • 待补充…