Skip to content

Go

安装软件

下载二进制 SDK https://golang.org/dl/

在 macOS 平台上,安装多个版本

  1. 先安装任意版本 x Go ;

  2. 再通过 x 版本安装指定版本 Go ,依次执行:

    go install golang.org/dl/go1.20.14@latest
    go1.20.14 download

  3. 默认 GOROOT 为 $HOME/sdk/go1.20.14

Ubuntu 22.04

通过 snaps 安装 snap install go --classic

使用 VSCode 编译时可能报错找不到 go 软件包: Failed to run '/snap/bin/go env. The config change may not be applied correctly.

解决方法: 修改 settings.json

json
"go.alternateTools": {
  "go": "/snap/go/current/bin/go"
}

https://github.com/golang/vscode-go/issues/1411

Ubuntu/WSL

snap 在 WSL 上不可用,需要通过 PPA 仓库安装。

sh
sudo add-apt-repository ppa:longsleep/golang-backports
sudo apt update
sudo apt install golang-go

常用配置

Windows 上特定设置

非 MSI 安装,需设置环境变量

通过 go env 获得 GOPATH 值,修改 PATH

GOPATH=path\to\yours
PATH=%GOPATH%\bin

设置 Go modules 全局代理

Go 1.13 或更高版本:

go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct

macOS/Linux echo "export GOPROXY=https://proxy.golang.com.cn,direct" >> ~/.profile && source ~/.profile

Windows

  1. 右键 我的电脑 -> 属性 -> 高级系统设置 -> 环境变量
  2. 在 “[你的用户名]的用户变量” 中点击 “新建” 按钮
  3. 变量名 输入框并新增 GOPROXY
  4. 在对应的 变量值 输入框中新增 https://proxy.golang.com.cn,direct
  5. 最后点击 确定 按钮保存设置

其他环境变量

  • SDK 路径,如 GOROOT=/opt/go
  • 包、自由项目源码路径,如 GOPATH=$HOME/work/

常用工具行命令

列出包所有版本 go list -m -versions github.com/foo/bar

列出所有支持平台和架构 go tool dist list

跨平台编译,如构建苹果系统二进制包 CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -o main.bin main.go

将特定包替换为本地,修改 go.mod

txt
replace github.com/foo/bar => ../../somebody/pkg
replace github.com/foo/bar v0.0.1 => ../../somebody/pkg v0.0.1

安装私有包

shell
export GOPRIVATE=github.com/me
go get github.com/foo/bar@v1.2.3

列出当前目录下所有子包 go list ./...

执行当前目录下所有子包测试 go test ./...

执行指定函数名测试 go test -v <package> -run <testFuncName> ,例 go test -v github.com/foo/bar/httphandler -run TestSignIn_MethodPostSucc

启动本地文档服务 godoc -http=:6060 -goroot=/usr/local/opt/go/libexec

安装指定包二进制命令行工具指定版本

shell
go install github.com/foo/bar/cmd/cli@latest
go install github.com/foo/bar/cmd/cli@d322275ba002fe84e2f403a76b8d656de72d98ea

强制更新依赖模块到指定版本

shell
# 通过 git commit hash 7位字符 指定
git log -3 --abbrev-commit
go get -u github.com/foo/bar@4205fc0

# 或 git commit hash 32位
go get golang.org/x/exp@0cdaa3abc0fa025dc2a2a0a108082837b6caf787

查某个包(如 golang.org/x/sync )被哪些包依赖: go mod graph | grep golang.org/x/sync

常用模块

text/template

  • 每次渲染都读磁盘没有缓存,直接修改 HTML 后生效不需要重启进程
  • 支持简单模版嵌套
  • 不支持表达式
  • 支持 range迭代 with局域变量
  • 条件仅支持 bool

内置其他

  • 命令行参数 flag
  • JSON encoding/json
  • HTTP net/http
  • 字符串处理 strings

非内置其他 golang.org/x 此域名下的包均为 Go 团队维护的 Go 相关扩展、库和工具:

  • golang.org/x/time/rate 频率控制
    • 限制瞬间打印大量日志, hibiken/asynq 例子
  • pkg.go.dev/golang.org/x/oauth2 oauth2 package contains a client implementation for OAuth 2.0 spec.
  • golang.org/x/net
  • golang.org/x/image
  • golang.org/x/crypto
  • golang.org/x/text

go-gorm/gorm

go-gorm/gorm postgres driver 不支持 mysql 式 DSN https://gorm.io/docs/connecting_to_the_database.html

调试错误,批量插入时某个字段错误明细不会显示,调试时可改为插入单条记录,复现明细:

txt
db.Create(objs)
=>
db.Create(objs[0])

gin-gonic/gin

gin-gonic/gin GET 不能和 DELETE/UPDATE 重复一个 pattern ,比如

http
GET /foo/:pk
DELETE /foo/:pk
PUT /foo/:pk

会抛出重复 注册 handler,需改为

http
GET /foo/detail/:pk
DELETE /foo/:pk
PUT /foo/:pk

go-redis/redis

go-redis/redis 调试 lua 脚本

  • redis 服务端启动时 指定日志级别 verbose redis-server --loglevel verbose
  • 在脚本中通过 print(...) 指令打印日志
  • 在 redis-sever 服务端查看日志

mock

Comparison

PackageGo versionNote
go.uber.org/mock/mockgen>= Go 1.21✔️ Generic, the latest support Go 1.20 v0.4.0
github.com/golang/mock>= Go 1.16❌ Generic, the latest support Go 1.20 v1.6.0

常见问题

降 Go 版本依赖

  • 修改 go.mod go x.y,执行 go mod tidy
  • 输出模块依赖关系 go mod graph > go.mod.txt
  • 根据输出错误提示降依赖高版本 Go 为低版本,具体低版本可通过该模块的 go.mod 确定,如
    • golang.org/x/*,点击导航栏的切换 tag 确定 https://cs.opensource.google/go/x/sys/+/refs/tags/v0.30.0:go.mod
    • github.com/elastic/go-elasticsearch,点击导航栏的切换 branch/tag 确定 https://github.com/elastic/go-elasticsearch/blob/v8.11.1/go.mod

锁定版本支持为 <= 1.20.14 ,常见模块依赖 tag 版本

Go 非 main 源码目录的子模块

shell
go get golang.org/x/text@v0.22.0
go get golang.org/x/net@v0.35.0
go get golang.org/x/time@v0.10.0
go get golang.org/x/net/html@v0.35.0
go get golang.org/x/tools@v0.24.0
go get golang.org/x/sync@v0.11.0

go get golang.org/x/sys@v0.30.0
go get golang.org/x/crypto@v0.33.0

VSCode 依赖

shell
go install github.com/go-delve/delve/cmd/dlv@v1.21.2
go install golang.org/x/tools/gopls@v0.15.3
go install golang.org/x/tools/cmd/goimports@v0.9.3
go install honnef.co/go/tools/cmd/staticcheck@2023.1.3

其他

shell
# Mock
go get go.uber.org/mock@v0.4.0

# GORM
go get github.com/jackc/pgx/v5@v5.6.0

# gRPC & ConnectRPC
go get google.golang.org/protobuf@v1.34.2
go get connectrpc.com/connect@v1.16.2

# AWS SDK
go get github.com/aws/smithy-go@v1.20.3

# ElasticSearch
go get github.com/elastic/elastic-transport-go/v8@v8.7.0
go get github.com/elastic/go-elasticsearch/v8@v8.11.1
go get go.opentelemetry.io/otel@v1.24.0

Only one usage of each socket address is normally permitted on Windows 10

Solution

bat
netsh int ipv4 set dynamicport tcp start=1025 num=64511
netsh int ipv4 show dynamicport tcp

See also

断点调试

delve debug Go program

install delve go install github.com/go-delve/delve/cmd/dlv

调试指定 Go 包

shell
go list ./...
dlv debug github.com/foo/bar/cmd/cli

设置断点 b main.main

传参数 dlv debug github.com/foo/bar/cmd/cli —- -y 1900-2000 -o path/out/result.txt

Setup dlv on macOS

Install dlv and setup DevToolsSecurity:

shell
xcode-select --install

go get github.com/go-delve/delve/cmd/dlv

sudo /usr/sbin/DevToolsSecurity -enable

Example

shell
go list ./...

github.com/foo/bar

dlv debug github.com/foo/bar/cmd

break main.main

continue

l
s
n

Go: verifying module: checksum mismatch

Error

go: downloading github.com/giant-stone/go v1.0.2
go: github.com/giant-stone/go@v1.0.2: verifying module: checksum mismatch
        downloaded: h1:qyHFai9aFiOof4ONzc2RunS2vB6kK2zoaHlUizFSJZs=
        sum.golang.org: h1:XeKp1ZsD4ixoRNikMg9smonDzdQlXCqG/lilitDr7ZE=

SECURITY ERROR
This download does NOT match the one reported by the checksum server.
The bits may have been replaced on the origin server, or an attacker may
have intercepted the download attempt.

For more information, see 'go help module-auth'.

If you has custom env GOPROXY, set it to empty and try again:

set GOPROXY=

go get -v github.com/giant-stone/go@v1.0.2

or clean Go module cache and try again

go clean -modcache

go get -v github.com/giant-stone/go@v1.0.2

Released under the CC-BY-NC-4.0